EOF bit versus fail bit

I want to:
1) use ifstream::get(char &) and ifstream::read()

2) set std::ios_base::badbit and std::ios_base::failbit in ifstream::exceptions()

Problem: eofbit is set together with failbit.
Why couldn't the EOF bit be set before trying to read beyond the EOF and failing?!

How can I deal with this, other than by using stream iterators (because I'd need to iterate short int as well, and that doesn't work).
Last edited on
Why couldn't the EOF bit be set before trying to read beyond the EOF and failing?!

Streams are very general and can be used to read any kind of data. Not everything has a known end. Take for instance std::cin. It is not always possible to now if the user will enter more data or not.

How can I deal with this, other than by using stream iterators (because I'd need to iterate short int as well, and that doesn't work).

You are using get and read so I assume you are reading binary data (not text). Reading a short int would look something like this.
1
2
short value;
file.read(reinterpret_cast<char*>(&value), sizeof(value));
Streams are very general and can be used to read any kind of data. Not everything has a known end. Take for instance std::cin. It is not always possible to now if the user will enter more data or not.

OK, I didn't think of that.

You are using get and read so I assume you are reading binary data (not text). Reading a short int would look something like this.
1
2
short value;
file.read(reinterpret_cast<char*>(&value), sizeof(value));


The problem is: how to differentiate between failed input and end of file? Because if I set failbit to throw an exception, while ( read() ) will always cause an exception to be thrown.
One way is to turn off exceptions for failbit and check if eofbit is not set after the loop and in that case throw the exception yourself.
> how to differentiate between failed input and end of file?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <sstream>
#include <string>

int main()
{
    std::istringstream stm( "12 34 56 78 abc" ) ;
    int n ;

    while( stm >> n ) ;
    // fail, not eof
    std::cout << "fail? " << std::boolalpha << stm.fail()
              << "    eof? " << stm.eof() << '\n' ;

    stm.clear() ;
    std::string str ;
    stm >> str ; 
    // eof, not fail
    std::cout << "fail? " << stm.fail()
              << "   eof? " << stm.eof() << '\n' ;

    stm.clear() ;
    stm >> str ;
    // fail and eof
    std::cout << "fail? " << stm.fail()
              << "    eof? " << stm.eof() << '\n' ;
}


Topic archived. No new replies allowed.