Search code examples
c++filestreamiostreameof

C++: std::istream check for EOF without reading / consuming tokens / using operator>>


I would like to test if a std::istream has reached the end without reading from it.

I know that I can check for EOF like this:

if (is >> something) 

but this has a series of problems. Imagine there are many, possibly virtual, methods/functions which expect std::istream& passed as an argument. This would mean I have to do the "housework" of checking for EOF in each of them, possibly with different type of something variable, or create some weird wrapper which would handle the scenario of calling the input methods.

All I need to do is:

if (!IsEof(is)) Input(is);

the method IsEof should guarantee that the stream is not changed for reading, so that the above line is equivalent to:

Input(is)

as regards the data read in the Input method.

If there is no generic solution which would word for and std::istream, is there any way to do this for std::ifstream or cin?

EDIT: In other words, the following assert should always pass:

while (!IsEof(is)) {
  int something;
  assert(is >> something);
}

Solution

  • That's impossible. How is the IsEof function supposed to know that the next item you intend to read is an int?

    Should the following also not trigger any asserts?

     while(!IsEof(in))
     {
        int x;
        double y;
        if( rand() % 2 == 0 )
        {
           assert(in >> x);
        } else {
           assert(in >> y);
        }
     }
    

    That said, you can use the exceptions method to keep the "house-keeping' in one place.

    Instead of

       if(IsEof(is)) Input(is)
    

    try

       is.exceptions( ifstream::eofbit /* | ifstream::failbit etc. if you like */ )
       try {
         Input(is);
       } catch(const ifstream::failure& ) {
       }
    

    It doesn't stop you from reading before it's "too late", but it does obviate the need to have if(is >> x) if(is >> y) etc. in all the functions.