#c #iostream
Вопрос:
Следующий фрагмент кода взят из C Iostreams Handbook by Steve Teale
. Он предлагает вызывать cin в бесконечном цикле, чтобы пользователю постоянно предлагался правильный ввод, и только когда вводится правильный ввод, мы выходим из цикла.
Этот фрагмент кода работает правильно, но меня смущает if(cin){...}
утверждение. Я бы ожидал чего-то подобного if(!cin.fail()){...}
.
#include <limits.h>
#include <iostream>
using namespace std;
int main()
{
int n;
cin.unsetf(ios::skipws);
// turn off whitespece skipping
cout << "Enter a value for n, followed by [Enter]: " << flush;
for(;;) {
cin >> n;
if(cin) { //cin is in good state; input was ok
cin.ignore(INT_MAX, 'n');
// flush away the unwanted
// newline character
break;
}
// Poster's comment (not from the author)
// In this section of the code cin has evaluated to false
//
cin.clear(); // clear the error state
cin.ignore(INT_MAX, 'n');
// get rid of garbage characters
cout << "That was no good, try again: " << flush;
}
return 0;
}
В) Как cin вычисляет значение false (т.Е. нулевое или нулевое значение) в случае сбоя?
cin — это объект, а не указатель, для которого можно установить значение null. Кроме того, в разделе кода, где cin принимает значение false, мы все еще можем вызывать функции-члены, такие как clear
and ignore
.
Комментарии:
1. Они только что изменили логику. Цикл представляет собой непрерывный цикл чтения, который прерывается только при получении правильных входных данных. Это прекрасный способ сделать это. Примечание:
cin.ignore(INT_MAX, 'n');
очистка после правильного ввода в случае, если после чтения целого числа были какие-либо посторонние символыn
, например"4 and other stuff"
. Что также является хорошей практикой.2. @DavidC.Rankin как cin принимает значение False? Пожалуйста, пролейте некоторый свет на это.
3. Каждый раз, когда возникает ошибка (например
badbit
, илиfailbit
установлено), состояние потока будет оцениватьfalse
, проверяете ли выif (cin)
илиif (cin.good())
. В обоих случаях, если установлен бит ошибки, условие равноfalse
.4. @DavidC.Rankin есть ли какая-то магия перегрузки оператора, которая позволяет использовать cin в логическом контексте (в
if
инструкции)? Кажется, что-то большее, чем кажется на первый взгляд. Пожалуйста, укажите мне на какую-нибудь ссылку, и я соответствующим образом просветлю себя.5. См. std::basic_ios::operator bool и std ::ios_base::iostate . Он будет проверяться
true
наgoodbit
oreofbit
,false
иначе.
Ответ №1:
То, что вы наблюдаете, является результатом наследования и неявного преобразования. Более конкретно, std::cin
имеет operator bool()
функцию, которая преобразует состояние потока в логическое значение, и этот оператор возвращает !fail()
.
std::cin
является глобальным std::basic_istream
, предоставляемым стандартной библиотекой, и basic_istream
наследуется от std::basic_ios
которой определяет функцию operator bool()
Цепочка наследования:
std::ios_base <-- std::basic_ios <-- std::basic_istream
Вы можете найти таблицу внизу этой веб-страницы полезной для сравнения operator bool()
с другими функциями проверки состояния потока и различными флагами состояния потоков.