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

Pra*_*bhu 17 c++ iostream

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

我有以下代码:

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

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

与以下情况非常相似:

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

Fre*_*urk 32

你非常非常想要检查坏,eof和好.特别是对于eof(as!stream.eof()是一个常见的错误),当前处于EOF的流并不一定意味着最后的输入操作失败; 相反,不参加EOF并不意味着最后的输入是成功的.

所有流状态函数 - 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);
Run Code Online (Sandbox Code Playgroud)

要阅读和处理所有行:

for (std::string line; getline(stream, line);) {
  process(line);
}
Run Code Online (Sandbox Code Playgroud)

有意思的是,good()被错误命名,并不等同于测试流本身(上面的例子就是这样).

  • @KeithB:你可能会注意到我离开了"应该很少检查"组.失败的流是重要的,检查流本身几乎总是比等效的fail()更方便.将getline(stream,line)与!getline(stream,line).fail()进行比较. (2认同)

Fre*_*Foo 9

只是用

ifstream f("x.txt");
while (getline(f, line)) {
    // whatever
}
Run Code Online (Sandbox Code Playgroud)

这是编写这样一个循环的惯用方法.我无法重现错误(在Linux机器上).