Почему cin, ожидающий int, изменяет соответствующую переменную int на ноль в случае недопустимого ввода?
Я совершенно не знаком с С++ и пытаюсь написать чрезвычайно базовую программу, но у меня возникают проблемы с инициализацией целого числа. Я разделил его на очень маленькую программу, которая все еще имеет проблему:
#include <iostream>
using namespace std;
int main()
{
cout << "Please enter your age\n";
int age = -1;
cin >> age;
cout <<"\n\n Your age is " << age << "\n\n";
}
Я прочитал, что если я попытаюсь ввести строку, например. abc
в переменную age
, тогда вход должен выйти из строя, и значение должно быть оставлено в покое, и поэтому оно должно печатать Your age is -1
.
Однако, когда я запускаю эту программу и набираю abc
, она печатает Your age is 0
. Почему?
Ответы
Ответ 1
Поведение, которое вы хотите наблюдать, изменилось в 2011 году. До тех пор:
Если извлечение завершится неудачно (например, если была введена буква, где ожидается цифра), значение остается неизмененным и устанавливается failbit.
Но так как С++ 11:
Если извлечение завершилось неудачно, нуль записывается в значение и устанавливается failbit. [...]
(Из cppr.)
Ответ 2
С компилятором, который я тестировал против (gcc 4.8.4), значение устанавливается равным нулю (для входа "abc" ) независимо от того, какая версия стандарта я компилируется. Обратите также внимание на то, что оно задано минимальным/максимальным значением, если вы указываете допустимое целое число, которое находится за пределами поддерживаемого диапазона переменной, которую вы назначаете.
Более важным моментом является то, что игнорирование флагов ошибок - это рецепт катастрофы. После появления ошибки на входе любой последующий ввод является подозрительным (без хаков, таких как ignore()). Подобные ситуации являются хорошим кандидатом на использование обработки исключений.
Вот как я могу реализовать то, что вы пытаетесь сделать (но, опять же, рассматривая случай с несколькими входами, восстановление из ошибок - беспорядочный бизнес):
cin.exceptions( ~std::ios::goodbit );
try { cin >> age; }
catch ( std::ios::failure const & )
{
age=-1;
cin.clear();
cin.ignore(999,'\n');
}
или без каких-либо исключений:
cin >> age;
if ( cin.fail() ) age=-1, cin.clear(), cin.ignore(999,'\n');
См. здесь похожие вопросы:
Ниже приведены современные документы для данного оператора: