Question

I'm trying to parse a file using std::istream and want to use exceptions to simplify error handling. But the stream never throws exceptions on eof even though they are enabled.

Consider the following snippet:

std::string line("Lorem ipsum");
std::istringstream is(line);
is.exceptions(std::ios::eofbit | std::ios::failbit);

std::string value1, value2, value3;
is >> value1;
std::cout << is.eof() << std::endl;
is >> value2;
std::cout << is.eof() << std::endl;
is >> value3;
std::cout << is.eof() << std::endl;

After reading value2, eof() returns true but no exception gets thrown at any time even though the stream is instructed to do so (see line 3). At the end, value3 contains an empty string.

What am I missing?

In case it matters: I'm using the LLVM libc++ that is part of Xcode 4.6.1 (LLVM C++ with C++11 support).

Était-ce utile?

La solution

I've just reviewed both the libc++ implementation and the parts of the standard which specifies this behavior:

27.7.2.1 Class template basic_istream [istream]/p3:

If rdbuf()->sbumpc() or rdbuf()->sgetc() returns traits::eof(), then the input function, except as explicitly noted otherwise, completes its actions and does setstate(eofbit), which may throw ios_base::failure (27.5.5.4), before returning.

And then p4:

If one of these called functions throws an exception, then unless explicitly noted otherwise, the input function sets badbit in error state. If badbit is on in exceptions(), the input function rethrows the exception without completing its actions, otherwise it does not throw anything and proceeds as if the called function had returned a failure indication.

I believe the crux here is the interpretation of "one of these called functions." I interpreted that phrase to refer to all of the functions mentioned in the preceding paragraph, including setstate(eofbit). Under that interpretation, libc++'s behavior is correct since badbit is not set.

To get the behavior you desire, do:

is.exceptions(std::ios::eofbit | std::ios::failbit | std::ios::badbit);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top