std::getline() 未读取没有“\n”的输入文件的最后一行

std::getline() is not reading last line of input file that has no '\n'

提问人:Rocco Ruscitti 提问时间:12/12/2019 更新时间:12/12/2019 访问量:3857

问:

尝试读取/打印文件的内容,其中最后一行不以“\n”结尾。程序只是错过了这些数据

while ( !readFile.eof() ) {
    string s;
    getline( readFile, s );
    if ( readFile.eof() ) break;
  //operate on data...
    cout << s << endl;
}
换行符 EOF GetLine

评论


答:

4赞 Remy Lebeau 12/12/2019 #1

请参考 为什么 iostream::eof 在循环条件中(即 'while (!stream.eof())')被认为是错误的?

您需要将调用直接移动到语句中:std::getline()while

string s;
while ( getline( readFile, s ) ) {
  //operate on data...
  cout << s << endl;
}

循环将一直运行,直到到达并且没有更多数据要读取。最后一行是否用换行符分隔无关紧要,因为即使没有分隔,也会做正确的事情并返回最后一行的数据。EOFstd::getline()

所以,实际上即使它没有分隔,也确实会返回最后一行,但你只是忽略了它,因为这个逻辑:std::getline()

getline( readFile, s );
if ( readFile.eof() ) break;
//operate on data...

如果最后一行没有分隔,则过早中断循环,因为在读取时遇到它时会打开,但实际上将包含最后一行的数据,然后您忽略这些数据。std::getline()eofbitreadFileEOFs

通过将 直接移动到语句中,它将依赖于流的布尔值转换运算符,该运算符将返回 if is set 并且没有设置任何错误标志 ( 或 ),允许循环处理非分隔行。当下一个循环迭代尝试读取过去时,将对流进行设置,导致运算符返回,中断循环。std::getline()whiletrueeofbitfailbitbadbitEOFstd::getline()failbitboolfalse

image

评论

0赞 Rocco Ruscitti 12/12/2019
仅当最后一行数据包含“\n”时,此方法才有效
0赞 Remy Lebeau 12/12/2019
@RoccoRuscitti事实并非如此。如果最后一行没有换行符,则只需读取直到 EOF,在流上设置,然后返回它读取的任何内容。当设置 only 时,流的运算符返回 true,因此循环不会在 EOF 本身中断。只有当尝试读取过去的 EOF 时,才会在流上设置,运算符将返回 false,从而中断循环。std::getline()eofbitbooleofbitstd::getline()failbitbool
0赞 Rocco Ruscitti 12/12/2019
我希望这是真的,但是我今天写的程序没有产生这个结果,除非我使用三元条件
0赞 Remy Lebeau 12/12/2019
@RoccoRuscitti 请参阅我对您关于三元运算符的回答的评论。它不会做你认为它所做的事情
0赞 Rocco Ruscitti 12/12/2019
我知道发生了什么:当我使用您的解决方案时,我忘记使用打印函数重新编译我的 .cpp 文件,然后再尝试使用三元运算符,所以它似乎不起作用,但正如您所说,三元解决方案是具有冗余的相同解决方案