2013-03-18 73 views
0

我的程序旨在從包含標題和作者列表的文件中獲取輸入。該文件看起來像這樣:搜索並行數組

 
title 
associated author 
next title 
associated author 
etc. 

我遇到的問題是我showBooksByTitle和showBooksByAuthor功能。此時此代碼僅返回完全匹配,並且還打印一個空白換行符和一個帶有一些空格和一個()的新行。

當然,任何幫助,非常感謝。這是我第一年編程。我已經包含了整個代碼,以保證安全,我不會遺漏任何可能成爲問題的東西。

#include <iostream> 
#include<string> 
#include<fstream> 
#include<cstring> 

using namespace std; 

struct Book { 
    string title; 
    string author; 
}; 

const int ARRAY_SIZE = 1000; 
Book books [ARRAY_SIZE]; 

int loadData (string); 
void showAll (int); 
int showBooksByAuthor (int, string); 
int showBooksByTitle (int, string); 

int main() { 
    //Declare variables 
    string pathname; 
    string title; 
    string name; 
    string word; 
    int count; 
    char response; 

    //ask user for pathname 
    cout << "What is the path of the library file? "; 
    cin >> pathname; 
    cout << endl; 
    count = loadData(pathname); 

    //input data into arrays 
    loadData(pathname); 
    cout << endl << count << " records loaded successfully." << endl << endl; 

    //Show user menu 
    cout << "Please enter Q to Quit, A to search for the Author, T to search for the Title, " 
    << endl << "or S to Show all: "; 
    cin >> response; 

    switch(response) { 
     case 'q': 
      break; 
     case 'Q': 
      break; 
     case 'a': 
      cout << endl << "Please enter author's name: "; 
      cin >> name; 
      showBooksByAuthor(count, name); 
      break; 
     case 'A': 
      cout << endl << "Please enter author's name: "; 
      cin >> name; 
      showBooksByAuthor(count, name); 
      break; 
     case 't': 
      cout << endl << "Please enter all or part of the title: "; 
      cin >> title; 
      showBooksByTitle(count, title); 
      break; 
     case 'T': 
      cout << endl << "Please enter all or part of the title: "; 
      cin >> title; 
      showBooksByTitle(count, title); 
      break; 
     case 's': 
      cout << endl; 
      showAll(count); 
      break; 
     case 'S': 
      cout << endl; 
      showAll(count); 
      break; 
     default: 
      cout << endl << "Invaled input, please try again: "; 
      break; 
    } 

    //pause and exit 
    cout << endl; 
    system("PAUSE"); 
    return 0; 
} 


int loadData(string pathname) { 
    int i = 0; 
    int j = 0; 
    ifstream library; 

    //open file, if not successful, output error message 
    library.open(pathname.c_str()); 
    if (!library.is_open()) { 
     cout << "Unable to open input file." << endl; 
     return -1; 
    } 
    //reads title and author from file into designated string 
    //this is assuming title comes first and author comes after 
    while(!library.eof()) { 
     getline(library, books[i].title); 
     getline(library, books[i].author); 
     i++; 
    } 
    return i; 
} 

void showAll (int count) { 
    for (int i = 0; i < count; i++) { 
     cout << books[i].title << " (" << books[i].author << ")" << endl; 
    } 
} 

int showBooksByAuthor(int count, string name) { 
    int found; 
    for(int n = 0; n < 28; n++) { 
     found = name.find(books[n].author); 
     if(found != string::npos) { 
      cout << endl << books[n].title << " (" << books[n].author << ")" << endl; 
     } 
    } 
    return 0; 
} 


int showBooksByTitle (int count, string title) { 
    int found; 
    for(int n = 0; n < 28; n++) { 
     found = title.find(books[n].title); 
     if(found !=string::npos) { 
      cout << endl << books[n].title << " (" << books[n].author << ")" << endl; 
     } 
    } 
    return 0; 
} 
+3

什麼是'28' ...? – 2013-03-18 11:52:51

+0

啊,是的,這段代碼從文本文件中讀取,文本文件中列出了28本書。我將附加該文件,但在此處看不到任何選項。我可以將它粘貼 – Jason 2013-03-18 11:54:40

+1

你不應該從'loadFile'保存返回值,並將它用作其他函數的n參數嗎?硬編碼「幻數」被認爲是不好的。考慮一下編輯文件do _not_包含28個條目時會發生什麼。 – 2013-03-18 11:56:33

回答

1

意外的輸出是因爲您讀取的數據文件錯誤。直到之後,流EOF標誌纔會被設置,然後您試圖對流進行操作,因此您的循環會迭代一次或多次。

改變回路中loadData這樣:

while(getline(library, books[i].title) && getline(library, books[i].author)) 
    i++; 

這使用了std::getline返回流,以及流可以作爲一個真/假值的事實。

+0

嗯,這是有道理的!我還需要回報嗎?然後? – Jason 2013-03-18 12:01:54

+0

@Jason你還能知道你加載了多少條目嗎?它可以是(返回'i + 1')或使用'std :: vector'(我會推薦)。 – 2013-03-18 12:04:21

1

約阿希姆已經指出了主要問題。我想添加一些評論意見:

  1. C++有一個可變長度數組,std::vector。它也有一個鏈表和其他容器。所以不要讓這些書成爲一個固定的數組,而是使用一些標準的容器。
  2. 使用迭代器而不是索引遍歷事物。對於數組指針是迭代器(C++ 11具有end()函數可以使指針剛好超過數組的末尾;在C++ 03中編寫自己很簡單,但不應該使用普通的舊數組)。
  3. 您正在查找輸入字符串中的書名/標題。如果你想要子串匹配,你應該以相反的方式來做。
+0

這是一個很棒的提示,謝謝你的提問,我一定會記住這一點。不幸的是,我不能使用這個矢量來完成這個任務,因爲我們還沒有在課堂上評論它。 – Jason 2013-03-18 12:11:25

+0

你能澄清3.?我跟着前兩個,但我不知道如何做found = name.find(books [n] .author);另一種方式。 – Jason 2013-03-18 12:18:59

+0

@Jason Simple,'found = books [n] .author.find(name);' – john 2013-03-18 12:44:06