Как мне не дать сканеру отбросить исключения, когда введен неправильный тип?
-
21-09-2019 - |
Вопрос
Вот какой -то пример кода:
import java.util.Scanner;
class In
{
public static void main (String[]arg)
{
Scanner in = new Scanner (System.in) ;
System.out.println ("how many are invading?") ;
int a = in.nextInt() ;
System.out.println (a) ;
}
}
Если я запускаю программу и даю ей int
как 4
, тогда все идет нормально.
С другой стороны, если я отвечу too many
Это не смеется над моей забавной шуткой. Вместо этого я получаю это (как и ожидалось):
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:819)
at java.util.Scanner.next(Scanner.java:1431)
at java.util.Scanner.nextInt(Scanner.java:2040)
at java.util.Scanner.nextInt(Scanner.java:2000)
at In.main(In.java:9)
Есть ли способ заставить его игнорировать записи, которые не являются ints или re -быстрыми с помощью «Сколько вторгается?» Я хотел бы знать, как сделать оба этого.
Решение
Вы можете использовать один из многих hasNext*
Методы, которые Scanner
имеет для предварительной проверки.
if (in.hasNextInt()) {
int a = in.nextInt() ;
System.out.println(a);
} else {
System.out.println("Sorry, couldn't understand you!");
}
Это предотвращает InputMismatchException
даже от того, что меня бросили, потому что вы всегда следите за тем, чтобы это БУДУТ Совместите, прежде чем прочитать его.
java.util.Scanner API
boolean hasNextInt()
: Возвращаетtrue
Если следующий токен в вводе этого сканера может быть интерпретирован как значение int в Radix по умолчанию с помощьюnextInt()
метод Сканер не продвигается мимо какого -либо ввода.String nextLine()
: Достигает этого сканера за текущую линию и возвращает вход, который был пропущен.
Имейте в виду разделы жирным шрифтом. hasNextInt()
не продвигается мимо какого -либо вклада. Если он возвращается true
, вы можете продвинуть сканер, позвонив nextInt()
, который не будет бросить InputMismatchException
.
Если он возвращается false
, тогда вам нужно пропустить «мусор». Самый простой способ сделать это - просто позвонить nextLine()
, вероятно, дважды, но хотя бы один раз.
Почему вам может понадобиться nextLine()
дважды - следующее: предположим, что это введенный вход:
42[enter]
too many![enter]
0[enter]
Допустим, сканер находится в начале этого вклада.
hasNextInt()
правда,nextInt()
возврат42
; сканер сейчас в Непосредственно первый[enter]
.hasNextInt()
ложь,nextLine()
Возвращает пустую строку, второйnextLine()
возврат"too many!"
; сканер сейчас в сразу после секунда[enter]
.hasNextInt()
правда,nextInt()
возврат0
; сканер сейчас в Непосредственно третий[enter]
.
Вот пример соединения некоторых из этих вещей. Вы можете экспериментировать с ним, чтобы изучить, как Scanner
работает.
Scanner in = new Scanner (System.in) ;
System.out.println("Age?");
while (!in.hasNextInt()) {
in.next(); // What happens if you use nextLine() instead?
}
int age = in.nextInt();
in.nextLine(); // What happens if you remove this statement?
System.out.println("Name?");
String name = in.nextLine();
System.out.format("[%s] is %d years old", name, age);
Допустим, ввод:
He is probably close to 100 now...[enter]
Elvis, of course[enter]
Тогда последняя строка вывода:
[Elvis, of course] is 100 years old
Другие советы
В общем, мне действительно не нравится использовать один и тот же библиотечный вызов как для чтения, так и для анализа. Языковые библиотеки кажутся очень негибкими и часто просто не могут быть склонны к вашей воле.
Первый шаг, который извлекает данные из System.in, не должен быть в состоянии выйти из строя, поэтому он прочитал их как строку в переменную, а затем преобразовать эту строковую переменную в Int. Если преобразование не удается, отлично-подайте свою ошибку и продолжайте.
Когда вы оберните свой поток чем -то, что может бросить исключение, это становится сбивая с толку, в каком состоянии весь беспорядок оставляет ваш поток.
Это всегда выгодно для имеют Ваше приложение бросает ошибку, когда возникает ошибка, против способов хранить это происходит.
Одна альтернатива - обернуть код внутри try {...}
catch {...}
Блок для InputMismatchException
Анкет Вы также можете закупить код внутри while
петля, чтобы иметь Scanner
Продолжайте подсказывать, пока не будет выполнено определенное состояние.