Ответ 1
Существуют три флага, которые указывают состояние ошибки:
-
badbit
означает, что что-то пошло не так с потоком. Это может быть ошибка буфера или ошибка в том, что подает данные в поток. Если этот флаг установлен, вероятно, вы больше не будете использовать поток. -
failbit
означает, что извлечение или чтение из потока завершилось неудачно (или запись или вставка для выходных потоков), и вам нужно знать об этом сбое. -
eofbit
означает, что входной поток достиг своего конца, и нет ничего, что можно было бы прочитать. Обратите внимание, что это устанавливается только после того, как вы попытаетесь прочитать из потока ввода, который достиг своего конца (то есть он установлен, когда возникает ошибка, потому что вы пытаетесь прочитать данные, которых там нет).
failbit
также может быть задан многими операциями, которые достигают EOF. Например, если в потоке осталось только пробел, и вы попытаетесь прочитать int
, вы оба достигнете EOF, и вы не сможете прочитать int
, поэтому оба флажка будут установлены.
Функция fail()
проверяет badbit || failbit
.
Функция good()
проверяет !(badbit || failbit || eofbit)
. То есть, поток хорош, когда ни один из битов не установлен.
Вы можете reset использовать флаги с помощью функции члена ios::clear()
; это позволяет вам установить любой из флагов ошибки; по умолчанию (без аргумента), он очищает все три флага.
Потоки не перегружают operator bool()
; operator void*()
используется для реализации некорректной версии безопасной идиомы bool. Эта перегрузка оператора возвращает значение null, если установлено значение badbit
или failbit
, а в противном случае - ненулевое значение. Вы можете использовать это для поддержки идиомы тестирования успеха извлечения в качестве условия цикла или другого оператора потока управления:
if (std::cin >> x) {
// extraction succeeded
}
else {
// extraction failed
}
Перегрузка operator!()
противоположна operator void*()
; он возвращает true
, если установлены badbit
или failbit
и false
в противном случае. Перегрузка operator!()
больше не нужна; это датируется до того, как перегрузки операторов были полностью и последовательно поддержаны (см. вопрос sbi "Почему std:: basic_ios перегружает оператор унарного логического отрицания?" .
С++ 0x исправляет проблему, которая заставляет нас использовать безопасную идиому bool, поэтому в С++ 0x шаблон базового класса basic_ios
перегружает operator bool()
в качестве явного оператора преобразования; этот оператор имеет ту же семантику, что и текущий operator void*()
.