#c #error-handling #cin #numeric-limits
#c #обработка ошибок #cin #числовые ограничения
Вопрос:
Итак, я полагаю, что я помещу это здесь, поскольку мне пришлось просмотреть множество документов и форумов, чтобы найти окончательный ответ. Я пытался получить входные данные от пользователя и проверить, является ли ввод целым числом, используемым isdigit()
в операторе if. Если оператор if не выполняется, программа выдает сообщение об ошибке. Хотя, когда вводился нецифровый символ, программа бесконечно просматривала сообщение об ошибке. Вот этот код:
int guess = -1;
while (game.getCurQuestion() <= 4) {
std::cout << "Guess: " << game.getCurQuestion() 1 << std::endl;
std::cin >> guess;
if(isdigit(guess))
{
game.guess(guess);
else
{
std::cout << "Errorn"; //this would be looped endlessly
}
}
std::cout << "You got " << game.getCorrect() << " correct" << std::endl;
return 0;
}
ПРИМЕЧАНИЕ: Решаемая, опубликованная только для включения моего решения. Не стесняйтесь исправлять, если я что-то неправильно указал.
Ответ №1:
Опубликованный способ иногда завершается ошибкой и преобразует удвоения в целые числа, если вводятся какие-либо удвоения.
Используйте что-то вроде следующего
int getIntInput() {
try {
std::string input;
std::cout << "nPlease Enter a valid Integer:t";
std::cin >> input;
size_t takenChars;
int num = std::stoi(input, amp;takenChars);
if (takenChars == input.size()) return num;
} catch (...) {}
return getIntInput();
}
Комментарии:
1. Мне нравится этот, поскольку он также позволяет избежать цикла cin при вводе символа. Это определенно выглядит намного лучше, чем странный оператор cin.ignore . Мой единственный вопрос: я слышал, что использование catch(…) было плохой практикой, считается ли это приемлемым в данном случае использования?
2. @CrypticEthosIt здесь неплохо, потому что я знаю причину исключения и пытаюсь получить новый ввод, который позволяет избежать выдачи того же исключения.
3. Ах, я вижу, что изначально в моем коде был смысл, у меня действительно был try catch, но я убрал его из-за (…), еще раз спасибо!
Ответ №2:
Проблема: программа сохранила нецелочисленное значение, сохраненное в буфере cin. Это приводит к тому, что программа никогда не выводит сообщение об ошибке.
Решение:
- Используется
std::cin.fail()
для проверки соответствия входных данных переменному типу данных. Т.Е.int
ожидаемый ввод, но пользователь ввел achar
. В этом случаеstd::cin.fail()
это было бы правдой. - В случае
std::cin.fail()
, используйтеstd::cin.clear()
иstd::cin.ignore(std::numeric_limits<int>::max(), 'n')
std::cin.clear()
сбросит флаг ошибки.std::cin.ignore(std::numeric_limits<int>::max(), 'n')
Будет игнорироваться любой другой ввод, который не является целым числом, и перейдет к новой строке. Эффективное продвижение программы.
Решение, реализованное в моем коде, выглядит следующим образом:
int guess = -1;
while (game.getCurQuestion() <= 4) {
std::cout << "Guess: " << game.getCurQuestion() 1 << std::endl;
std::cin >> guess;
if (std::cin.fail())
{
std::cout << "Please enter a valid numbern";
std::cin.clear();
std::cin.ignore(std::numeric_limits<int>::max(), 'n');
}
game.guess(guess);
}
Надеюсь, это поможет и избавит некоторых людей от утомительных исследований из-за того, что они никогда не учатся std::cin
обработке ошибок! Примечание: я знаю, что моя реализация пропускает текущий ход, назовите это наказанием 😉
Комментарии:
1. Примечание: asmmo дал очень хороший ответ выше, который сводит на нет необходимость в std ::cin.clear() и std ::cin.ignore() , что также предотвращает ввод двойных значений в этом варианте использования