Почему cin, ожидая int, изменяет соответствующую переменную int на ноль в случае неверного ввода?
Я совершенно новичок в C++ и пытаюсь написать чрезвычайно простую программу, но у меня возникают проблемы с инициализацией целого числа. Я сократил его до очень маленькой программы, которая все еще имеет проблему:
#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
, Зачем?
2 ответа
Поведение, которое вы хотите наблюдать, изменилось в 2011 году. До тех пор:
Если извлечение завершается неудачно (например, если буква была введена там, где ожидается цифра), значение остается неизменным, и бит сбоя устанавливается.
Но начиная с C++11:
Если извлечение завершается неудачно, в значение записывается ноль, и бит сбоя устанавливается. [...]
(Из cppr.)
С компилятором, с которым я тестировал (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');
Смотрите здесь для похожих вопросов:
Вот последние документы для рассматриваемого оператора: