Определенный ввод с плавающей точкой ломает программу на C++
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
int dlina;
cout << "Введите длину действительного массива меньшую или равную 30: ";
while (true) {
cin >> dlina;
if (dlina > 30 || dlina < 1){
printf("Некорректное значение! Введите еще раз: ");
}
else break;
}
}
Проблема в том, что если число до точки не соответствует условию, то оно ломает терминал и цикл продолжается бесконечно, например, число -2.73. Каким самым простым способом это можно исправить?
Ответы (2 шт):
При ошибке формата, cin переходит в состояние ошибки, поэтому ваш цикл не завершается. Для "исправления", например, при чисто интерактивном использовании, можно попробовать так:
while (!(cin >> dlina) || dlina > 30 || dlina < 1) {
if (cin.eof() || cin.bad()) {
cerr << "Конец файла или ошибка В/В.\n";
return -1;
}
cout << "Некорректное значение! Введите еще раз: ";
cin.clear();
// Пропускаем остаток строки (с некорректными символами,
// или, возможно, только '\n', при нарушении границ)
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
Следует заметить, что при входной строке: "4.2", dlina считается, как 4, а ".2" останутся несчитаными в cin для последующих операций ввода.
P.S.
При использовании в общем виде, а не в main(), может быть удобно вместо if (cin.eof() || cin.bad())... вызвать до цикла cin.exceptions(~cin.failbit) - выбрасывать исключение std::ios_base::failure при любой ошибке, кроме ошибки формата.
Всё элементарно - когда в потоке ввода встречается точка или любой другой символ, который не ожидается при вводе целого числа, то этот символ не забирается из потока, а остаётся в нём. То есть вы можете ввести даже просто одну точку вместо числа - и получить такое же поведение вашего кода. В dlina в этом случае попадает 0, срабатывает if с печатью ошибки, а некорректный символ остаётся в потоке, читается из него заново, опять печатается ошибка и т.д.
Введите длину действительного массива меньшую или равную 30: .
Некорректное значение! Введите еще раз:
Некорректное значение! Введите еще раз:
Некорректное значение! Введите еще раз:
Некорректное значение! Введите еще раз:
...
(вывод будет без переводов строк, я их добавил для читаемости)
Про исправление есть другой ответ, я не знаю C++, советовать не возьмусь.