无限使用 getline() 运行 匹配单词 c++ 程序?
Matching word c++ program using getline() running infinitely?
我正在学习 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
它编译正确,但是当我 运行 它在我的终端中时,没有任何显示;它似乎永远不会停止加载。
我该如何解决这个问题?
如果出现问题并且您到达文件末尾,循环将永远不会停止。您应该将 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;
}
除非你真的 想在早上讨厌自己(可以这么说),否则你想改掉使用全局变量的习惯。如果将 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;
}
}
这仍然不完美(例如,格式不正确的输入仍可能导致它失败)但至少这是朝着我所说的更好方向迈进了一步。
// 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))
,
我正在学习 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
它编译正确,但是当我 运行 它在我的终端中时,没有任何显示;它似乎永远不会停止加载。 我该如何解决这个问题?
如果出现问题并且您到达文件末尾,循环将永远不会停止。您应该将 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;
}
除非你真的 想在早上讨厌自己(可以这么说),否则你想改掉使用全局变量的习惯。如果将 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;
}
}
这仍然不完美(例如,格式不正确的输入仍可能导致它失败)但至少这是朝着我所说的更好方向迈进了一步。
// 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))
,