Когда сканер выдает исключение InputMismatchException, сканер не передает токен, вызвавший исключение, так что его можно извлечь или пропустить каким-либо другим методом.
Это означает, что если следующий токен не является int, он выбрасывает InputMismatchException, но токен остается там. Итак, на следующей итерации цикла reader.nextInt() снова считывает тот же токен и снова создает исключение. Что вам нужно, так это использовать его. Добавьте reader.next() внутри вашегоcatch, чтобы использовать токен, который недействителен и должен быть удален.
... } catch (InputMismatchException e) { System.out.println("Invalid value!"); reader.next(); // this consumes the invalid token }
Ответ 2
Что я бы сделал, так это прочитал всю строку с помощью Scanner.nextLine() . Затем создайте другой сканер, который считывает возвращенную строку.
Таким образом, у вас есть один сканер, который получает входные данные, и один, который проверяет их, поэтому вам не нужно беспокоиться о том, что читателю будет небезразлично, вводит ли он правильную форму ввода.
Ответ 3
Защита вашего while-do - это переменная 'loop'.
Само исключение, генерируемое до того, как ваш код достигнет цикла присваивания = false; Если быть точным, исключение генерируется в предыдущем операторе, который является num = reader.nextInt();
При возникновении исключения значение переменной 'loop' равно 'true', но ваш код переходит к блоку catch, а затем повторяет while-do . Это while-do никогда не остановится, потому что следующая итерация снова выдаст исключение, снова перейдет к блоку перехвата и так далее.
Чтобы завершить это while-do , вам нужно защитить свой while-do другой логической вещью, такой как :
Выход, когда считыватель получает символ, отличный от int
Выход при EOF
Это можно сделать в блоке catch или некоторых других строках. Но точное решение зависит от ваших спецификаций.