Как мне не дать Сканеру генерировать исключения, если введен неправильный тип?
Вот пример кода:
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)
Есть ли способ заставить его игнорировать записи, которые не являются целочисленными, или вывести сообщение "Сколько вторгаются?" Я хотел бы знать, как сделать оба этих.
3 ответа
Вы можете использовать один из многих 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 в основании по умолчанию, используя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
продолжайте подсказывать, пока не будет выполнено определенное условие.