The difference is very slight.
The first piece of code, tries reading as long as it doesn't hit EOF condition. Then it breaks. But, if for some reason an error occurrs (i.e. failure to convert data through <<
operator), this piece of code will loop indefinitely, since FAIL will be set on error, reading will stop, and EOF will never be hit.
The second piece of code works with a small trick. It reads as long as it can and stops when error occurs. Ok, logical. However, when hittin an end-of-file, but IIRC the EOF condition will not be set yet. So, the loop will run once more, try to read at EOF state, and that will rise the FAIL flag and break the loop. But that also means that you will get one processing ( cout<
The right way to do is to check immediatelly whether READING succeeded:
while (true){
if(!(Ifstream >> Buffer))
break;
cout << Buffer << endl;
}
only that will guarantee you that the loop will stop as soon as read fails, be it EOF or FAIL or other cause.
As MatsPetersson and πάντα ῥεῖ have suggested, the above snippet may be "squashed" to form:
while (Ifstream >> Buffer)
cout << Buffer << endl;
and that's the usual way to write it. No fail/good/eof
checks needed. The value returned from operator>>
is the stream itself (like in operator<<
) and stream is testable for "truthness", so it's just as simple as that. When talking about fail/good/eof differences, I like to write the longer form to emphasize that .. you shouldn't use fail/good/eof in the while-condition at all, and that you should check the state of the stream only after actually trying to read from it. while(true)
shows the point very clearly.