Почему устанавливается failbit при вводе EOF?

#c #linux #qt #operating-system #iostream

#c #linux #qt #операционная система #iostream

Вопрос:

В настоящее время я изучаю, как while (cin >> num) это работает, и обнаружил, что есть два шага. Первый — это оператор>> функция, возвращающая объект istream с состоянием ошибки, а второй — конвертер bool, который преобразует объект istream в bool в зависимости от его состояния.

Но меня смущает то, что в функции преобразования bool она возвращает 0, только если установлен failbit или badbit. И оператор>> функция установит eofbit, если он прочитает EOF.

функция преобразования bool: https://www.cplusplus.com/reference/ios/ios/operator_bool /

оператор>> функция: >/» rel=»nofollow noreferrer»>https://www.cplusplus.com/reference/istream/istream/operator>> /

В этом случае после ввода EOF конвертер bool должен вернуть 1, потому что failbit и badbit не установлены.

Поэтому я использую приведенную ниже программу, чтобы проверить, что на самом деле произошло с битом ошибки после ввода EOF. И я узнаю, что failbit будет установлен после ввода EOF!!

Итак, мне интересно, может ли кто-нибудь помочь мне понять, почему установлен failbit?

 #include <iostream>

using namespace std;

int main()
{
    int num;
    cin >> num;
    cout << cin.eof() << " " << cin.fail() << " " << cin.bad() << endl;
    return 0;
}
 

Ввод: ^Z (в Windows с использованием qt creator, не qt c project)
Вывод: 1 1 0

Ввод: ^D (в Windows с использованием qt creator, не qt c project) Вывод: 0 1 0

Ответ №1:

eofbit устанавливается, когда операция чтения сталкивается с EOF при чтении данных в буфер потока. Данные еще не обработаны.

failbit устанавливается, когда запрошенные данные не могут быть извлечены из буфера, например, при чтении целого числа с operator>> помощью . Во время ожидания поступления цифр может возникнуть EOF. eofbit одного недостаточно для ввода состояния ошибки, так как в буфере могут быть полезные данные.

Итак, например, представьте while (cin >> num) , что используется цикл, и пользователь входит 123<Ctrl-Z> .

  • на 1-й итерации operator>> считывает 1 , 2 , 3 в буфер, затем встречает Ctrl-Z, поэтому он устанавливает eofbit и прекращает чтение. 123 затем извлекается из буфера в num , и оператор завершает работу. На данный момент поток еще не находится в состоянии ошибки. Когда bool преобразование потока оценивается с помощью while , оно возвращает true , позволяя вводить while тело, чтобы оно могло обрабатываться num .
  • на следующей итерации operator>> eofbit устанавливается значение sees, предотвращающее дальнейшее чтение. В буфере ничего не осталось для извлечения num , поэтому оператор устанавливает failbit и завершает работу. Поток теперь находится в состоянии ошибки. Когда bool преобразование потока оценивается с помощью while , оно возвращает false , прерывая while цикл.

Комментарии:

1. Большое вам спасибо!! Ваше объяснение очень четкое!! Я всегда думал, что именно из-за EOF завершается программа. Не знал, что char или double могут иметь тот же эффект ~

2. Кстати, вы знаете, что означает Ctrl D в Windows? Если я нажму Crtl D, он установит только failbit, и все, что я могу найти в Интернете, говорит только о том, что Crtl D делает в ОС на базе unix.

3. @Benasking7124 Ctrl D на самом деле ничего не делает в окне cmd Windows, оно обрабатывается как управляющий символ ( ^D ) . Однако он что-то делает в контексте других приложений (например, в Проводнике он переместил выбранный файл в корзину)

4. О, я понимаю!! Это потому, что символ ^D не принимается типом int, который запускает failbit правильно? (точно так же, как если бы я ввел «abc» в переменную int) Не потому, что есть какое-то особое значение Crtl D

5. @Benasking7124 да, точно

Ответ №2:

Если EOF является первым вводом, operator>> не удается прочитать целое число, поэтому поток переходит в fail() состояние.

Если вы введете хотя бы одну цифру перед Ctrl-Z, эта цифра будет считана, и ввод завершится успешно.

Комментарии:

1. Спасибо за ваше объяснение ~