Не работает проверка на корректность ввода
Существует код, в котором нужно ввести номер домашней работы. Суть в том, что работ, скажем, 5. Так вот при вводе любого значения кроме 1-5 программа должна вывести: "Введённые данные некорректны". Я попытался реализовать проверку следующим образом:
int taskNumber;
bool isCorrectNumber;
while (true) {
cout << "Для просмотра заданий введите номер задания (1-5)" << endl;
cout << endl;
cout << "№1 - задание \"Имя\"" << endl;
cout << "№2 - задание \"Арифметика\" "<< endl;
cout << "№3 - задание \"Уравнение\" "<< endl;
cout << "№4 - задание \"Ещё уравнение\" "<< endl;
cout << "№5 - задание \"Лампа со шторой\" "<< endl;
cout << endl;
isCorrectNumber = 0;
do {
cin >> taskNumber;
if (taskNumber > 0 && taskNumber < 6) {
isCorrectNumber = 1;
}
else {
taskNumber = 0;
cout << "Вы ввели некорректный номер задания, вам необходимо ввести значение от 1 до 5 (1, 2, 3, 4, 5)" << endl;
cout << endl;
}
} while (isCorrectNumber == 0);
cout << "Ты вышел из ментальной тюрьмы, ежже" << endl;
}
Суть в том, что при вводе числа, которое не является номером задания всё работает как надо и начинается новый ввод. Однако если ввести какое-то слово, то консоль начнёт спамить "Вы ввели некорректный номер задания, вам необходимо ввести значение от 1 до 5 (1, 2, 3, 4, 5)"
Ответы (3 шт):
Потому что если вы вводите не число - оно остается в буфере ввода, а поток переходит в состояние fail - и никакого чтения уже больше нет...
Вот, возьмите готовый вариант с проверкой корректности ввода и диапазона:
int inputInt(const char * prompt, int m = INT_MIN, int M = INT_MAX)
{
int N;
for (;;) {
std::cout << prompt << " (целое от " << m << " до " << M << "): " << std::flush;
if ((std::cin >> N).good() && (m <= N) && (N <= M)) return N;
if (std::cin.fail()) {
std::cin.clear();
std::cout << "Неверный ввод, повторите.\n";
} else {
std::cout << "Число вне допустимого диапазона значений. Повторите ввод.\n";
}
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
}
}
a = inputInt("Введите размер массива",1,10);
int taskNumber;
bool isCorrectNumber = false;
do{
cout << "Для просмотра заданий введите номер задания (1-5)" << endl;
cout << endl;
cout << "№1 - задание \"Имя\"" << endl;
cout << "№2 - задание \"Арифметика\" " << endl;
cout << "№3 - задание \"Уравнение\" " << endl;
cout << "№4 - задание \"Ещё уравнение\" " << endl;
cout << "№5 - задание \"Лампа со шторой\" " << endl;
cout << endl;
cin >> taskNumber;
if (taskNumber > 0 && taskNumber < 6) {
isCorrectNumber = true;
}
else {
taskNumber = 0;
cout << "Вы ввели некорректный номер задания, вам необходимо ввести значение от 1 до 5 (1, 2, 3, 4, 5)" << endl;
cout << endl;
};
cout << "Ты вышел из ментальной тюрьмы, ежже" << endl;
} while (!isCorrectNumber);
прошу заметить я саму логику ввода не менял , я изменил ее конструкцию
Немного переделал оответ Гарри - надо бы еще проверять на ввод дабла. из Моих изменений
- добавил чек на дабл
- использую стрингвью а не голый указатель
- использую лимиты
- логически разделил ввод и чек на инт и чек на лимит
Вот измененный код
#include <iostream>
#include <string>
#include <limits>
#include <string_view>
int GetIntFromCin(std::string_view prompt) {
double input{0x0};
while (true) {
input = 0x0;
std::cout << prompt << " : " << std::flush;
if ((std::cin >> input).good()) {
if (input == static_cast<int>(input)) {
break;
}
std::cout << std::endl << "You Inter a Float or Double! Try agane!" << std::endl << std::flush;
}
if (std::cin.fail()) {
std::cin.clear();
std::cout << std::endl << "Wrong Retry please:" << std::endl << std::flush;
}
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
}
return static_cast<int>(input);
}
int GetIntFromCinWithLimits(std::string_view prompt, int min = std::numeric_limits<int>::min(), int max = std::numeric_limits<int>::max()) {
int ret{0};
while (true) {
ret = GetIntFromCin(prompt);
if (ret < min || ret > max) {
std::cout << std::endl << "Wrong By limits!" << std::endl << std::flush;
continue;
}
break;
}
return ret;
}
int main() {
int val = GetIntFromCinWithLimits("Enter nun", 0, 100);
std::cout << "You enter a " << val << std::endl;
return 0;
}