However, C++ programmers note that what always happens is that cin.eof() doesn't return "true" until after the last line has been read twice.
That is not what is happening. The eofbit
plays no a role in the conversion to a boolean (stream::operator bool
(or operator void*
in older c++)). Only the badbit
and failbit
are involved.
Suppose you are reading a file containing numbers separated by whitespace. A loop based around cin.eof()
will inevitably be either wrong or be chock full of if
tests. You aren't reading until EOF. You are reading numbers. So make your code express that logic:
while (stream >> some_var) {
process_value(some_var);
}
This will work whether the last line of the file ends with 0 42\n
or just 0 42
(no new line at the end of the last line in the file). If the file ends with 0 42\n
, the last good read will retrieve the value 42 and read that final end of line marker. Note that the EOF marker has not yet been read. The function process_value
is called with 42
. The next call to the stream extraction operator >> reads the EOF, and since nothing has been extracted, both the eofbit
and failbit
will be set.
Suppose on the other hand, the file ends with 0 42
(no newline at the end of the last line). The last good read will retrieve the value 42 terminating on the EOF marker. Presumably you want to process that 42. This is why the eofbit
does not play a role in the input stream boolean conversion operator. On the next call to the stream extraction operator >>, the underlying machinery quickly sees that the eofbit
is already set. This quickly results in setting the failbit
.
Why does the first piece of code always fail to work properly?
Because you shouldn't be checking for EOF as the loop condition. The loop condition should express what you are trying to do, which is (for example), extracting numbers from a stream.