2017-05-19 39 views
0

我希望能夠循環打開和關閉文件以不斷搜索名稱。更適合從文件中循環輸入的方法?

第一次沒問題,輸出是預期的,那麼當選擇y時,會出現輸出循環。

任何想法爲什麼會發生這種情況?邏輯似乎不僅僅是正確的。

#include <iostream> 
#include <fstream> 
#include <string> 
using namespace std; 

int main() 
{ 
    string boys, girls, name; 
    int rank; 
    char end = 'n'; 
    while (end != 'y' || end != 'Y') 
    { 
     cout << "Enter a name to search"; 
     cin >> name; 
     ifstream input; 
     input.open("Names2016"); 
     if (input.fail()) 
      cout << "Failed to open file.\n"; 
     while (!input.eof()) 
     { 
      input >> rank >> boys >> girls; 
      if (boys == name) 
       cout << name << " ranks " << rank << " among boys.\n"; 
      if (girls == name) 
       cout << name << " ranks " << rank << " among girls.\n"; 
     } 
     input.close(); 
     cout << "Would you like to search another name?\n" 
      << "Enter Y for yes or N for no.\n"; 
     cin >> end; 
    } 
    return 0; 
} 
+1

http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong使用。 –

+0

我們能否看到您的Names2016文件? – Tyger

+0

我很新,不確定如何向您顯示文件。它由一個等級,一個空間,與該等級相關聯的男孩名字,一個空間以及與該等級相關聯的女孩名字組成,然後進入新的行。我從https://www.ssa.gov/cgi-bin/popularnames.cgi中提取信息,但您必須將格式調整爲1000個名稱。我非常抱歉,我不知道如何給你確切的文件 – NewToThis

回答

0

這裏有一些事情可以做,以使此代碼更好,

  1. 首先是使用ifstreams並做文件輸入/輸出在一個循環的正確習慣的方法,不使用.eof()在循環條件下檢查文件的結尾(如果你想知道爲什麼,註釋中鏈接的答案是一個很好的開始的地方),
  2. 你想用一個簡單的if (!file)來檢查文件有效性的第二件事它更清潔的海事組織。
  3. 第三件事,當你有一個像你在你的代碼中一樣的本地文件句柄時,你可以讓它超出範圍,讓析構函數清理文件,它是C++ RAII的做法事情(請注意,我已經刪除了open()方法構造函數調用(它做同樣的事情)
  4. 使用cerr而不是cout報告錯誤
  5. 使用char而不是int表示字符
  6. 沒有大的變化,但使用std::toupper就像在其他答案的評論中建議的一樣是一個很好的易讀的方式在同一時間

#include <iostream> 
#include <fstream> 
#include <string> 
#include <cctype> 
using namespace std; 

int main() 
{ 
    string boys, girls, name; 
    int rank; 
    char end = 'n'; 
    while (std::toupper(end) == 'Y') 
    { 
     cout << "Enter a name to search"; 
     cin >> name; 
     ifstream input{"Names2016"}; 

     // change here 
     if (!input) { 
      cerr << "Failed to open file.\n"; 
     } 

     while (input >> rank >> boys >> girls) 
     { 
      if (boys == name) 
       cout << name << " ranks " << rank << " among boys.\n"; 
      if (girls == name) 
       cout << name << " ranks " << rank << " among girls.\n"; 
     } 
     // change below, just let the file handle go out of scope and close 
     // input.close(); 
     cout << "Would you like to search another name?\n" 
      << "Enter Y for yes or N for no.\n"; 
     cin >> end; 
    } 
    return 0; 
} 

檢查大寫和小寫值,但你可以對我做的更好/ O如果你的文件是不能保證的變化通過不同的迭代(在這種情況下,您可能需要確保沒有競爭,所以我假設文件沒有太大變化)。讀取文件中的一次,保存的信息稍後

#include <iostream> 
#include <fstream> 
#include <string> 
#include <cctype> 
#include <unordered_map> 
#include <vector> 
using namespace std; 

int main() 
{ 
    string boys_name, girls_name, name; 
    int rank; 
    char end = 'n'; 
    ifstream input{"Names2016"}; 
    if (!input) { 
     cerr << "Failed to open file" << endl; 
    } 

    // preprocess the information and store it in a map 
    // making a map from string to vector because it is unclear whether 
    // there is a 1-1 mapping from the name to the rank for each name 
    unordered_map<string, vector<int>> boys; 
    unordered_map<string, vector<int>> girls; 

    while (input >> rank >> boys_name >> girls_name) { 
     boys[boys_name].push_back(rank); 
     girls[girls_name].push_back(rank); 
    } 

    while (std::toupper(end) == 'Y') 
    { 
     cout << "Enter a name to search"; 
     cin >> name; 

     // use the map to do the lookup, much faster than reading 
     // the entire file over and over again    
    } 
    return 0; 
} 
+1

謝謝你對你錯綜複雜的想法感到好奇。第一個選項絕對符合我目前對C++的理解。但是,您的意思是(!輸入)而不是(輸入)? – NewToThis

+0

@新到這是的我做到了,很好! – Curious

0

首先,這到底意味着int end = 'n';你指定一個字符的整數?

爲什麼你打開循環內的同一個文件。您應該在程序開始時只打開一次。

eof沒有要檢查的內容,因爲您必須從文件中讀取以達到其結尾。

+1

它需要'結束!='y'&& end!='Y''。更好的是,'toupper(end)!='Y''。 –

+0

閱讀我的結賬cout聲明。我問用戶是否想繼續,因此,我的while循環不應該說(end ='y'|| end =「y」) – NewToThis

+0

@NewToThis更正,對不起,我的壞!那麼'int end ='n';'這會給出一個錯誤,你不能給int賦一個字符值,你應該做的是'char end ='n';' – 2017-05-19 03:47:44