C++ - 标准输入循环

C++ - Standard Input Loop

Stroustrup 的 Programming Principles and Practice Using C++ (2e, ch 10, print 6) 给出了以下惯用语 -- 稍微修改以使其独立和可编译 -- 对于迭代地从输入流中读取直到遇到 EOF 或指定的终止符,对于任何其他停止条件抛出异常。

#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
}

程序注释和周围的说明暗示 EOF 是结束此迭代读取的一种可接受的(不会导致错误的)方式。但是当我在诸如以下不包含终止符的两行文本文件之类的文件上进行测试时,

3 1 4 1 5
9 2 6 5 3

抛出异常 ("bad termination of input")。一个例外是我所期望的——在读取最后的 '3' 之后,后续读取遇到 EOF,导致流的 eofbit 被翻转,但读取也失败,导致 failbit 被翻转。该成语似乎假定 eofbit 和 failbit 是相互排斥的。

这个习语是否有用,或者它在 EOF 案例的处理方式上是否存在逻辑错误?

根据 this state reference failbit

input/output operation failed (formatting or extraction error)

引用还说 failbit 已设置

if either eofbit or badbit is already set on the stream, or if the end of stream is encountered while consuming leading whitespace

因此遇到输入本身的结尾不会设置 failbit,但尝试再次读取将设置 failbit