2015-12-21 2 views
2

В настоящее время я самостоятельно изучаю C++ Primer 5th. Вот что-то я не уверен. (Я не мог найти точный актуальный вопрос о F.A.Q).Как оценивается значение «std :: cin >>» в цикле while?

Рассмотрим это время цикла:

while(std::cin>>value){...} \\value here was defined as int. 

текст книги говорит:

Это выражение читает следующий номер из стандартного ввода и магазинов, количество стоимости. Оператор ввода (§ 1.2, стр. 8) возвращает свой левый операнд, который в этом случае является std :: cin. Это условие, следовательно, проверяет std :: cin. Когда мы используем istream как условие, эффект заключается в проверке состояния потока. Если поток действителен, то есть, если поток не обнаружил ошибку, тогда тест будет успешным.

Мой вопрос: делает std::cin читать ввод в value первую затем проверить проверку std::cin, или тест std::cin первый затем решить, следует ли читать в «ценности»? Я довольно смущен, когда он «возвращает свой левый операнд».

+0

Зная, что значение 'std :: cin >>' просто 'std :: cin.operator >> (value)' может помочь вам. – Holt

ответ

9

Помните, что ваш код эквивалентен:

while (std::cin.operator>>(value)) { } 

Или:

while (1) { 
    std::cin >> value ; 
    if (!std::cin) break ; 
} 

"код" всегда пытается прочитать из std::cin в value перед тестированием std::cin.

Давайте посмотрим на цитаты:

[...] Входной оператор (§ 1.2, стр. 8) возвращает левый операнд, который в данном случае является станд :: CIN. [...]

Это означает, что std::cin.operator>>(value) возвращение std::cin.

Это условие, следовательно, проверяет std :: cin. Когда мы используем istream в качестве условия, эффект заключается в проверке состояния потока. Если поток действителен, то есть, если поток не обнаружил ошибку, тогда тест будет успешным.

Что говорит текст книги является то, что при попытке прочитать целое число от std::cin до value, оператор >> возвращает std::cin. Если std::cin находится в хорошем состоянии после прочтения value, тогда тест проходит, в противном случае он терпит неудачу.


Некоторые дополнительные детали:

Когда вы делаете std::cin >> value, вы в основном называют istream::operator>>(int&) и да есть тест внутри этот метод: Если тест пройден, то внутреннее состояние std::cin установлен на ios_base::goodbit, если он не работает, внутреннее состояние установлено на значение флага ошибки (eofbit, failbit или badbit).

В зависимости от exception mask для std::cin, если внутреннее тестирование не выполнено, исключение may be thrown.

С вашей цитате:

Когда мы используем IStream как условие, эффект, чтобы проверить состояние потока.

В основном это означает, что:

if (std::cin) { } 

Является equivalent к:

if (!std::cin.fail()) { } 

И std::cin.fail() чек на failbit или badbit. Это означает, что while (std::cin >> value) { } не проверяет флаг eofbit и будет терпеть неудачу, если вход не может быть преобразован в целочисленное значение.

+0

Огромное вам спасибо! T.T Ваш второй пример спас мою жизнь, Теперь все ясно для меня. – Des1gnWizard

+0

Спасибо за усилия T.T. – Des1gnWizard

2

Существует два теста.

Первый тест является состояние в то время как заявление

while(std::cin>>value){...} 

Это условие проверяет результат вызова функции оператора operator >>

Второй тест является условием внутри оператора. Если состояние потока std::cin хорошее, тогда функция пытается прочитать целое число из строки. В противном случае он возвращает std::cin с текущим ошибочным состоянием std::cin.

В состоянии в то время как есть выражение

std::cin>>value 

Это выражение должно быть оценено. Таким образом, это условие проверяет результат вызова operator >>.

Результат оператора представляет собой поток std::cin Но это может быть контекстуально преобразуется в значение BOOL в связи с оператором

explicit operator bool() const; 

который возвращает состояние потока

!fail(). 
+0

Ваш ответ не является ошибочным, но (IMO) немного вводит в заблуждение, потому что ваше «второе условие» действительно будет выполнено до «первого теста». – Holt

+0

@Hoit Да, я сейчас сражался с двумя заданными ответами, спасибо за указание на это! – Des1gnWizard

0

Оператор первым читает значение и затем возвращает ссылку на объект. Оператор while сначала вызывает этот оператор и второй проверяет возвращаемое значение.

+0

Операция ITYM 'while'. –

+0

@MartinBonner Спасибо за исправление. – JSF

3

делает станд :: CIN чтения ввода в значение первого затем протестировать проверку станд :: CIN, или тест-STD :: CIN первый затем решить, следует ли читать в 'значение'

cin сначала пытается прочитать int со стандартного ввода, если cin находится в хорошем состоянии: если он не удался, он установит поток в плохое состояние; независимо от выполненной операции, он вернет сам поток (т. е. «левый операнд» - cin), что позволит вам проверить успех или неудачу.

Если вы хотите явно проверить обоснованность потока первого и только затем попытаться прочитать значение, вы бы:

while (cin && cin >> value) 

но это довольно излишним, так как, как я уже говорил вам, cin даже не попытается прочитать value, если он уже в плохом состоянии.

+0

Спасибо за усилия! – Des1gnWizard

+0

Просто осознал, насколько краткими ваши слова. Я сейчас записываю ваши объяснения. Спасибо! – Des1gnWizard

1

Я полагаю, ваш «значение» является, например, INT

  • поток пытается не читать ввод до следующего пробела.

  • если ВФ найден ... -> то состояние будет установлено в «ВФ», >> возвращает поток и булеву оценку потока вернет ложное

  • если ошибка (I/O, например) происходит во время процесса чтения, состояние будет установлено как «плохое», >> вернет поток, и логическая оценка потока вернет false

  • если пробелы были найдены, то будет предпринято преобразование из прочитанных символов в int (указанное выше предположение). Если он терпит неудачу (поскольку вход чтения является, например: «xx», а не числом), состояние потока будет установлено на «fail». >> вернет поток, и логическая оценка потока вернет false

  • Если мы так далеко по цепочке, eof не был найден, ошибка IO (или другая) не была выполнена, а символы -> int преобразование было успешным. >> вернет поток, и булевская оценка потока вернет true.

    И ваше «значение» будет содержать соответствующее значение

+0

Спасибо за усилия! :) – Des1gnWizard

+0

На самом деле, когда установлен только 'std :: ios_base :: eofbit', поток не преобразуется в' false'! Поток преобразуется только в 'false', когда устанавливаются' std :: ios_base :: failbit' или 'std :: ios_base :: badbit'. 'std :: ios_base :: eofbit' устанавливается, например, при чтении последней строки файла, которая не завершается новой строкой. Линию можно с радостью прочитать и обработать. Только в случае сбоя операции ввода, например, когда делается попытка прочитать что-либо, когда установлен параметр 'std :: ios_state :: eofbit', поток устанавливается в режим, в котором он возвращает' false', обычно с помощью 'std: : ios_base :: failbit' set. –

1

Вероятно, у вас не будет иметь какой-либо путаницы с простой вызов функции:

SomeReturnType some_function(int&); 
while (some_function(value)) { ... } 

Приведенный выше код не будет повторно вызывать some_function до возвращаемое значение из вызова функции, интерпретируемое как логическое, равно false. Функция вызывается для каждого шага в цикле. Независимо от того, изменилась ли функция, значение value соответствует функции. Это, безусловно, может это сделать и, по-видимому, сделает это (но это проблема для дизайнера функции).

Петля while (std::cin>>value) {...} полностью эквивалентна while (std::cin.operator>>(value)) {...}. Это просто вызов функции функции-члена std::stream::operator>>(int&).

+0

Да, я понял, вот почему нужно сначала оценить ценность! Спасибо! – Des1gnWizard

Смежные вопросы