Stroustrup's Programming Principles and Practice Using C++ (2e, ch 10, print 6) gives the following idiom -- modified slightly to make it stand-alone and compilable -- for iteratively reading from an input stream until either EOF or a designated terminator character is encountered, with an exception thrown for any other stopping condition.
#include <iostream>
#include <stdexcept>
int main()
{
std::istream& is = std::cin;
char term = '|'; // terminator
for (int x; is >> x; ) {
// do something with x
}
if (is.bad()) {
throw std::runtime_error("bad input stream");
}
if (is.fail()) {
is.clear();
char c;
if (!(is >> c && c == term)) {
throw std::runtime_error("bad termination of input");
}
}
// carry on: we found EOF or terminator
}
The program comments and surrounding exposition imply that EOF is an acceptable (non-error-causing) way for this iterative read to end. But when I test this on files such as the following two-line text file containing no terminators,
3 1 4 1 5
9 2 6 5 3
an exception is thrown ("bad termination of input"). An exception is what I would expect -- after reading the final '3', the subsequent read encounters EOF, causing the stream's eofbit to be flipped, but the read also failed, causing the failbit to be flipped. The idiom seems to assume that eofbit and failbit are mutually exclusive.
Is this idiom serviceable or does it have a logical error in how the EOF case is handled?
According to this state reference the failbit
is
input/output operation failed (formatting or extraction error)
The reference also says failbit
is set
if either
eofbit
orbadbit
is already set on the stream, or if the end of stream is encountered while consuming leading whitespace
So encountering the end of the input itself doesn't set failbit
, but attempting to read again will set failbit
.