LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   c++ istream: throw exception for everything but eof (https://www.linuxquestions.org/questions/programming-9/c-istream-throw-exception-for-everything-but-eof-4175448351/)

hydraMax 02-02-2013 11:48 AM

c++ istream: throw exception for everything but eof
 
Hi. I'm not especially familiar with c++, but I am required to use it for a class. I wrote this little function:

Code:

int readLines(istream &in,
              int (*hand)(string))
{
  in.exceptions(istream::failbit | istream::badbit);
  while(in.good())
    {
      string uname;
      in >> uname;
      hand(uname);
    }
  return 0;
}

It is supposed to read in lines, and pass the lines to a handler function. I want it to keep reading lines as long as the input stream is in a good state, return 0 if it reaches eof, and throw an exception for any other input stream error.

However, when I tested this, it also throws an exception when eof is reached, which is not what I intended. How do I get it to not throw an exception on eof, but to throw an exception for everything else?

Code:

terminate called after throwing an instance of 'std::ios_base::failure'
  what():  basic_ios::clear
Aborted


dwhitney67 02-03-2013 07:37 AM

The problem is that when EOF is reached, the failbit is set, and hence the reason an exception is thrown.

I would suggest that you wrap your while-loop within a try-block, and then catch the ios_base::failure exception when it occurs. Then examine the eofbit to determine if the exception was thrown due to reaching the EOF, or due to some other reason. For the latter, merely re-throw the exception.

Code:

int readLines(istream &in, int (*hand)(string))
{
    ...

    try
    {
        while (in.good())
        {
            ...
        }
    }
    catch (ios_base::failure& e)
    {
        if (!in.eof())
        {
            throw ios_base::failure(e.what());
        }
    }

    return 0;
}



All times are GMT -5. The time now is 01:41 AM.