C ++ - Стандартный входной цикл - PullRequest
0 голосов
/ 20 января 2020

Stroustrup Принципы и практика программирования с использованием 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

выдается исключение («неправильное завершение ввода»). Исключением является то, что я ожидаю - после прочтения последнего «3» последующее чтение встречает EOF, вызывая переворачивание eofbit потока, но чтение также завершается неудачно, вызывая переворачивание failbit. Кажется, идиома предполагает, что eofbit и failbit являются взаимоисключающими.

Эта идиома исправна или имеет логическую ошибку в том, как обрабатывается случай EOF?

1 Ответ

2 голосов
/ 20 января 2020

Согласно эта ссылка на состояние failbit равна

Ошибка операции ввода-вывода (ошибка форматирования или извлечения)

Ссылка также говорит, что failbit установлено

, если либо eofbit, либо badbit уже установлено в потоке, либо если конец потока встречается при использовании начальных пробелов

Таким образом, встреча с концом самого ввода не устанавливает failbit, но попытка чтения снова установит failbit.

...