in.good() is true if the previous read operation was successful, but EOF does not occur. (It is possible that EOF occurs even if the read operation succeeds.) Therefore, if in.good() is false, or the previous read operation failed - in this case the next one will also fail - or the EOF was encountered - - in this case the next read operation will also fail. Therefore, if in.good() is false, the next read operation will definitely fail. If we want to know whether to do a read operation, we should test in.good() .
But the fact that in.good() true does not guarantee anything. Suppose in ends with a space, which usually happens because text files must end with a newline. Formatted read operations stop at the first space character, and unget back to the input stream, so if the previous read operation reads the last data item, it still does not leave the stream in EOF, and in will still be good . [Cm. Note 1]. Therefore, if your loop looks like this:
while (in.good()) { in >> x; /* Do something with x assuming that it is valid */ }
then you wonโt notice when the last in >> x ends, and you end using the undefined x value in the last loop. (Probably the last value will be processed twice.)
The same thing happens if your loop was while (!in.bad()) or while (!in.eof()) .
Are you sure you want to check if in >> x succeeded. Nothing more. And the classic way to do this:
while (in >> x) { /* If we get here, x has a legitimate value */ ... }
in >> x just returns in , so it is exactly equivalent
while (in >> x, in) { /* ... */ }
In other words, bool(in) is false exactly when the previous operation failed, and true exactly when it succeeded. This is not the same as in.good() , because we still do not want to check if EOF has been encountered.
Notes:
- As indicated in the first paragraph, reading can be successful, as well as installing EOF. One of the ways that this can happen is that the file does not end with a newline. This is pretty rare, but you shouldn't rule it out. And the fact that this can happen, which is why
in.bad() does not check the eof flag: in.bad() is false, which means that the previous read operation failed.