C++ 测试 stream.good() 或 !stream.eof() 读取最后一行两次

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4324441/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 15:07:20  来源:igfitidea点击:

Testing stream.good() or !stream.eof() reads last line twice

c++iostream

提问by Prabhu

Possible Duplicate:
Why is iostream::eof inside a loop condition considered wrong?

可能的重复:
为什么循环条件中的 iostream::eof 被认为是错误的?

I have the following piece of code:

我有以下一段代码:

ifstream f("x.txt");
string line;
while (f.good()) {
  getline(f, line);
  // Use line here.
}

But this reads the last line twice. Why does this happen and how do I fix it?

但这会读取最后一行两次。为什么会发生这种情况,我该如何解决?

Something very similar happens with:

非常相似的事情发生在:

ifstream f("x.txt");
string line;
while (!f.eof()) {
  getline(f, line);
  // Use line here.
}

回答by Fred Nurk

You very, very rarely want to check bad, eof, and good. In particular for eof (as !stream.eof() is a common mistake), the stream currently being at EOF does not necessarily mean the last input operation failed; conversely, not being at EOF does not mean the last input was successful.

你很少想检查 bad、eof 和 good。特别是对于 eof(因为 !stream.eof() 是一个常见的错误),当前处于 EOF 的流并不一定意味着最后一次输入操作失败;相反,不在 EOF 并不意味着最后一次输入成功。

All of the stream state functions – fail, bad, eof, and good – tell you the current state of the stream rather than predicting the success of a future operation. Check the stream itself (which is equivalent to an inverted fail check) after the desired operation:

所有的流状态函数——fail、bad、eof 和 good——告诉你流的当前状态,而不是预测未来操作的成功。在所需操作后检查流本身(相当于反向失败检查):

if (getline(stream, line)) {
  use(line);
}
else {
  handle_error();
}

if (stream >> foo >> bar) {
  use(foo, bar);
}
else {
  handle_error();
}

if (!(stream >> foo)) {  // operator! is overloaded for streams
  throw SomeException();
}
use(foo);

To read and process all lines:

读取和处理所有行:

for (std::string line; getline(stream, line);) {
  process(line);
}

Pointedly, good() is misnamed and is not equivalent to testing the stream itself (which the above examples do).

有针对性地, good() 被错误命名并且不等同于测试流本身(上面的例子就是这样)。

回答by Fred Foo

Just use

只需使用

ifstream f("x.txt");
while (getline(f, line)) {
    // whatever
}

This is the idiomatic way to write such a loop. I've not been able to reproduce the error (on a Linux machine).

这是编写此类循环的惯用方法。我无法重现该错误(在 Linux 机器上)。

回答by CashCow

It didn't read the last line twice but because it failed to read when it reached eof, your string line has the value it had previously.

它没有读取最后一行两次,但是因为它在到达 eof 时未能读取,所以您的字符串行具有它以前的值。

That is because f is no longer "good" when it has read EOF, not when it is about to read it.

那是因为 f 在读取 EOF 时不再“好”,而不是在即将读取它时。