xtofl
xtofl

Reputation: 41509

istream extraction operator: how to detect parse failure?

How can I detect whether the istream extraction failed like this?

string s("x");
stringstream ss(s);
int i;
ss >> std::ios::hex >> i;

EDIT -- Though the question title covers this, I forgot to mention in the body: I really want to detect whether the failure is due to bad formatting, i.e. parsing, or due to any other IO-related issue, in order to provide proper feedback (an malformed_exception("x") or whatever).

Upvotes: 5

Views: 7034

Answers (4)

xtofl
xtofl

Reputation: 41509

First off: thanks for the useful answers. However, after some investigation (cfr. cppreference) and verification, it seems that the one way to check for parse-failure only is by checking for the ios::failbit flag, as in

const bool parsing_failed = (ss >> ios::hex >> i).rdstate() & ios::failbit ;

While both the suggested istream::operator! and istream::operator bool mingle failbit and badbit (cfr here and there on cplusplusreference).

Upvotes: 0

01d55
01d55

Reputation: 1912

if(! (ss >> std::ios::hex >> i) ) 
{
  std::cerr << "stream extraction failed!" << std::endl;
}

It's just that easy.

ETA: Here's an example of how this test interacts with the end of a stream.

int i;
std::stringstream sstr("1 2 3 4");
while(sstr >> i)
{
    std::cout << i << std::endl;
    if(sstr.eof())
    {
        std::cout << "eof" << std::endl;
    }
}

will print
1
2
3
4
eof

If you were to check sstr.eof() or sstr.good() in the while loop condition, 4 would not be printed.

Upvotes: 9

Zappotek
Zappotek

Reputation: 384

Errors during extraction are signaled by the internal state flags. You can check them by the good() member function. See also here: http://www.cplusplus.com/reference/iostream/stringstream

Or just using the if()-construction as suggested above. This works due to the bool cast operator of stream classes

Upvotes: 0

Mike Seymour
Mike Seymour

Reputation: 254461

Failure to extract the value will set the stream's "fail" bit, which can be detected by if (ss.fail()), or just if (!ss). Equivalently, you can test the result of the >> operation, since that returns a reference to the stream.

These will also detect other errors, which set the "bad" bit; you can distinguish these with ss.bad().

If you want to continue reading from the stream, you'll need to clear the state flags (ss.clear()).

Upvotes: 5

Related Questions