Бесконечная петля с cin при наборе строки, в то время как число ожидается
В следующем цикле, если мы вводим символы как вход cin
вместо ожидающих чисел, то он переходит в бесконечный цикл. Может ли кто-нибудь объяснить мне, почему это происходит?
Когда мы используем cin
, если вход не является числом, существуют ли способы обнаружить это, чтобы избежать вышеупомянутых проблем?
unsigned long ul_x1, ul_x2;
while (1)
{
cin >> ul_x1 >> ul_x2;
cout << "ux_x1 is " << ul_x1 << endl << "ul_x2 is " << ul_x2 << endl;
}
Ответы
Ответ 1
Ну, у вас всегда будет бесконечный цикл, но я знаю, что вы действительно хотите знать, потому что cin не продолжает запрашивать ввод на каждой итерации цикла, заставляя ваш бесконечный цикл использовать freerun.
Причина в том, что cin не работает в описанной вами ситуации и больше не будет считывать эти переменные. Предоставляя отрицательный вход cin, cin получает в состоянии fail) и перестает запрашивать командную строку для ввода, что приводит к свободному запуску цикла.
Для простой проверки вы можете попытаться использовать cin для проверки своих входов путем проверки того, находится ли cin в состоянии сбоя. Когда сбой происходит очистить состояние отказа и заставить поток выбросить плохой ввод. Это возвращает cin для нормальной работы, поэтому вы можете запросить больше ввода.
if (cin.fail())
{
cout << "ERROR -- You did not enter an integer";
// get rid of failure state
cin.clear();
// From Eric answer (thanks Eric)
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Для более сложной проверки вы можете сначала прочитать строку и выполнить более сложные проверки строки, чтобы убедиться, что она соответствует ожидаемому.
Ответ 2
Внимание
Обратите внимание на следующее решение. Он еще не завершен, чтобы устранить ошибку в вашем случае. Вы все равно получите бесконечный цикл!
if (cin.fail())
{
cout << "Please enter an integer";
cin.clear();
}
Полное решение
Причина в том, что вам нужно очистить состояние отказавшего потока, а также отказаться от необработанных символов. В противном случае плохой символ все еще существует, и вы все равно получаете бесконечные циклы.
Для этого вы можете просто std:: cin.ignore(). Например,
if (cin.fail())
{
cout << "Please enter an integer";
// clear error state
cin.clear();
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Другое решение
Вы также можете использовать getline
и stringstream
для достижения. Вот краткий пример.
string input;
while (1)
{
getline(cin, input);
stringstream(input) >> x;
cout << x << endl;
}
Ответ 3
Возможно, это потому, что
- cin - это потоковая функция. Когда
вместо цифр вводится вместо
чисел, он игнорируется. И вы
запрос на повторный вход.
- Даже если вы указали числовые входы,
вам будет предложено ввести больше входов, поскольку вы находитесь в бесконечном цикле.
Вы можете решить эту проблему следующим образом:
1. Создайте функцию для ввода строкового ввода.
2. верните его как числовое после преобразования. Используйте strtod() для преобразования.
Надеюсь, что это поможет:)
Ответ 4
Другой альтернативой является operator!, это эквивалентно функции-члене не работают()
//from Doug answer
if ( !cin )
{
cout << "ERROR -- You did not enter an integer";
// get rid of failure state
cin.clear();
// From Eric answer (thanks Eric)
// discard 'bad' character(s)
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}