Using !eof()
, !fail()
, !bad()
, or !good()
, is invariably the wrong way to condition your input. The point is to perform the extraction first, and then check if succeeded. If you do the former, you'll almost always get the problems you are experiencing.
The first extraction into n
obtained 4
from the stream. After it found the newline it stopped and you printed the value of n
. When the second loop executed, the extractor cleared the leading whitespace from the stream (meaning the newline after 4
), found the end of the stream and set eofbit
. Since no characters were extracted, it also set failbit
. When you attempted to print the value again, all you were seeing was the result of the previous input operation.
This isn't the right way to perform a read. You have to do it before checking the stream. This is how it is commonly done:
while (in >> n)
{
std::cout << n << std::endl;
}
After the read is performed, operator bool()
will be invoked on the stream, which will access its stream state and determine if the extraction succeeded. If it did, only then will the loop body execute.