I'm a new learner of C++. In my understanding, fail() indicates whether the last operation on the istream/ostream succeeded or not. For example, let ifs be an ifstream opened to some valid file:
string s;
while (ifs >> s) {
// 1. assume the reading was taken successfully
// and do something according to that
}
// 2. assume the reading was unsuccessful
// and do something according to that
May I ask if it is possible that, in some (corner) cases, we arrive at 2. while the reading was actually successfully taken?
If so, what we do at 2. could be problematic. For example, if we have set ifs.exceptions(ifs.exceptions() | ios_base::badbit);, then we would (probably) have assumed that ifs is empty at 2..
I came up with this question when I was self-learning C++ using Stroustrup's book Programming: Principle and Practice Using C++ (2nd ed.). In Chapter 11.7 of this book, the writers design a Punct_stream class that takes an istream as source, processes data extracted from the source and then put the processed data into a data member of type istringstream called buffer waiting to be inputted into the program. The writers design the operator bool() method as follows (Page 404):
Punct_stream::operator bool()
{
return !(source.fail() || source.bad()) && buffer.good();
}
Firstly, I think !(source.fail() || source.bad()) should be equivalent to just checking source since fail() accounts for both failbit and badbit, and checking source is equivalent to checking !fail().
What is more related to my question is that, by this design, operator bool() will first check if the source is in an error state, and if so, it won't even look at the buffer. But reading data from a Punct_stream into a string will be done as long as there is character in buffer. So, if the buffer is not empty and the source is fail() somehow, then reading from the Punct_stream into a string will actually succeed while the checking on the Punct_stream condition will be false.
I wonder if the implementation of the standard library istreams may behave in some similar way such that in some cases the reading is actually successfully taken but the condition is evaluated to false?