开发者

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

This question 开发者_开发百科already has answers here: Closed 11 years ago.

Possible Duplicate:

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

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.
}


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.

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:

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).


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).


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.

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜