Testing stream.good() or !stream.eof() reads last line twice [duplicate]
Solution 1:
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).
Solution 2:
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).
Solution 3:
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.