0

I read a question on Stack Overflow where the eofbit for the istream file is set but the failbit is not. In that case file is true and file.eof() is true but file.good() is false. For example with a file exactly one byte in size:

ifstream file("one.txt");
assert( file.is_open() );
for( int i = 0; i < 2; ++i )
{
    char chars[255] = {0};
    file.getline(chars, 2);
    //file.read( chars, 2 );

    cout << "file: " << !!file << endl;
    cout << "good: " << file.good() << endl;
    cout << "eof: " << file.eof() << endl;
    cout << "fail: " << file.fail() << endl;
    cout << "bad: " << file.bad() << endl;
    cout << endl;
}

This is the output:

file: 1
good: 0
eof: 1
fail: 0
bad: 0

file: 0
good: 0
eof: 1
fail: 1
bad: 0

If I comment out the getline() and use read() instead, I get this:

file: 0
good: 0
eof: 1
fail: 1
bad: 0

file: 0
good: 0
eof: 1
fail: 1
bad: 0

In both cases I'm reading past the end of the file in the loop's first iteration. Why is one EOF and fail and one isn't? The answer in the other thread says "whenever you encounter the end of a file without attempting to read behind it." read behind it? What does that mean?

Community
  • 1
  • 1
loop
  • 3,460
  • 5
  • 34
  • 57

1 Answers1

5

The eofbit is set by the getline method if it stops reading because it hits the end of the stream (file), rather than by finding the delimiter character. getline does not set the failbit in that case, which is logical because it didn't fail: it read some data.

Once the eofbit is set, the next read operation on that stream will set the failbit, because the internal sentry function, called at the start of just about every input operation, will set failbit if eofbit is set.

In general, the eofbit "indicates that an input operation reached the end of an input sequence", while failbit "indicates that an input operation failed to read the expected characters" (both quotes are from the C++ standard, section [ios.types]; ยง27.5.3.1, table 124, in the latest draft I have lying around.) As the getline example shows, it is quite possible for an input operation to read the end of an input sequence, while still reading something.

Another, somewhat less formal -- and therefore possibly incorrect -- way of looking at this is that eofbit is set if the read operation reached the end of the file, whereas the failbit is set if the read operation could not read the minimum number of characters it required. The 2 in the calls to getline and read mean different things; in getline, it is the maximum number of characters for the input operation (the minimum number is 1); in the case of read, it is the precise number of characters.

rici
  • 234,347
  • 28
  • 237
  • 341