使用无限运行的getline()匹配单词c ++程序?

时间:2017-11-11 03:00:10

标签: c++ ifstream getline

我正在学习c ++所以请耐心等待,并事先为任何愚蠢的人道歉。

我正在尝试编写一些代码,这些代码与名为" command.txt"的文件中每行的第一个字匹配。至" num_lines"," num_words"或" num_chars"。

如果第一行的第一个单词与前面提到的单词不匹配,则会读取下一行。 一旦它击中匹配的单词(仅限第一个单词!),它就会打印出匹配的单词。

以下是我的所有代码:

#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

它正确编译,但当我在终端中运行时,没有任何显示;它似乎永远不会停止加载。 我该如何解决这个问题?

3 个答案:

答案 0 :(得分: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;
        }
}

这仍然不是完美的(例如,糟糕的输入仍然可能导致它失败)但至少它是我所说的更好的方向。

答案 1 :(得分: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;
} 

答案 2 :(得分: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))