2017-11-11 71 views
1

我正在學習C++,所以請耐心等待,並且事前爲任何白癡道歉。匹配使用getline()無限運行的單詞C++程序?

我試圖寫一些代碼,將每行上的第一個字匹配到「num_lines」,「num_words」或「num_chars」文件中,名爲「command.txt」。

如果第一行的第一個單詞與先前提到的單詞不匹配,它將讀取下一行。 一旦它遇到匹配的單詞(僅第一個單詞!)它打印出匹配的單詞。

這裏是我的所有代碼:

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

using namespace std; 

ifstream comm_in("commands.txt"); // opens file 
string command_name = "hi"; // stores command from file 


bool is_command() { 
    if (command_name == "num_words" || command_name == "num_chars" || command_name == "num_lines") { 
     return true; 
    } else { 
     return false; 
    } 
} 


// FIND a first word of a line in file THAT MATCHES "num_words", "num_chars" or "num_lines" 
void get_command() { 

    string line; 
    char c; 

    while (!is_command()) { // if command_name does not match a command 

     // GET NEXT LINE OF FILE TO STRING 
     getline(comm_in, line); 

     // SUPPOSED TO GET THE FIRST WORD OF A STRING (CANT USE SSTREAM) 
     for (int i = 0; i < line.size(); i++) { // increment through line 
      c = line[i]; // assign c as index value of line 

      if (c == ' ' || c == '\t') { // if c is a space/tab 
       break; // end for loop 
      } else { 
       command_name += c; // concatenate c to command_name 
      } // if 
     } // for 
    } // while 
    return; 
} 

int main() { 

    get_command(); 
    cout << command_name; // supposed to print "num_lines" 
} 

的command.txt文件的內容:

my bear is happy 
and that it 
great ha 
num_lines sigh 

編譯正確,但是當我在終端運行它,什麼也不顯示;它似乎永遠不會停止加載。 我該如何解決這個問題?

+0

看看你的'while'循環做。什麼會導致ti停止? – Jay

+0

while循環在is_command返回true時停止,即當command_name ==「num_lines」時,它一旦讀取到command.txt文件的第4行就必須停止?這個邏輯有什麼問題嗎? – Salvatross

+0

這是怎麼回事?一旦退出循環,它應該打印並退出程序。 – Jay

回答

0

如果出現問題並且您到達文件末尾,循環將永不停止。您應該將getline(comm_in, line)更改爲if(!getline(comm_in, line)) break;,或者更好,將其用作循環的條件。

您還可以重置command_name每一遍:

while(getline(comm_in, line)) 
{ 
    command_name = ""; 
    for(int i = 0; i < line.size(); i++) 
    { 
     c = line[i]; 
     if(c == ' ' || c == '\t') 
      break; 
     else 
      command_name += c; 
    } 
    if(is_command()) 
     break; 
} 
1

除非你真的要恨自己在早上(這麼說)你想擺脫使用全局變量的習慣。如果您將get_command分爲(至少)兩個函數(特別是從包含該行的字符串中獲取第一個字),您幾乎肯定會發現生活更簡單。

我會寫代碼更是這樣的:

bool is_cmd(std::string const &s) { 
    return s == "num_words" || s == "num_chars" || s == "num_lines"; 
} 

std::string first_word(std::istream &is) { 
    std::string line, ret; 

    if (std::getline(is, line)) { 
     auto start = line.find_first_not_of(" \t"); 
     auto end = line.find_first_of(" \t", start); 
     ret = line.substr(start, end - start); 
    } 
    return ret; 
} 

void get_command(std::istream &is) { 
    std::string cmd; 

    while (!(cmd = first_word(is)).empty()) 
     if (is_cmd(cmd)) { 
      std::cout << cmd; 
      break; 
     } 
} 

這仍然是不完美的(例如,形成嚴重的輸入可能仍然導致失敗),但至少它是什麼我一招d說是更好的方向。

0
// FIND a first word of a line in file THAT MATCHES "num_words", "num_chars" or "num_lines" 
void get_command() 
{ 
    string line; 
    char c; 

    while (!is_command()) { // if command_name does not match a command 

     // GET NEXT LINE OF FILE TO STRING 
     if(getline(comm_in, line),comm_in.fail()){ 
      // end reading 
      break; 
     } 

     //clear 
     command_name = ""; 

     // SUPPOSED TO GET THE FIRST WORD OF A STRING (CANT USE SSTREAM) 
     for (int i = 0; i < line.size(); i++) { // increment through line 
      c = line[i]; // assign c as index value of line 

      if (c == ' ' || c == '\t') { // if c is a space/tab 
       break; // end for loop 
      } else { 
       command_name += c; // concatenate c to command_name 
      } // if 
     } // for 
    } // while 
    return; 
} 

這個問題的關鍵是你沒有明確的command_name

更重要的是,您必須添加一個關於是否達到文件末尾的判斷。

PS:if(getline(comm_in, line),comm_in.fail())等於if(getline(comm_in, line))