Подтвердить что ты не робот

Почему 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. Почему?

4b9b3361

Ответ 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');

См. здесь похожие вопросы:

Ниже приведены современные документы для данного оператора: