Вот некоторый пример кода:
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 или подсказкой ре с, "Сколько вторгается?" Я хотел бы знать, как сделать оба из них.
Для предварительной проверки можно использовать один из многих методов hasNext*
, которые есть у Scanner
.
if (in.hasNextInt()) {
int a = in.nextInt() ;
System.out.println(a);
} else {
System.out.println("Sorry, couldn't understand you!");
}
Это предотвращает InputMismatchException
, потому что вы всегда убедитесь, что WILL совпадает до того, как вы его прочитаете.
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()
false, nextLine()
возвращает пустую строку, второй nextLine()
возвращает "too many!"
; сканер сейчас находится на сразу после второго [enter]
. hasNextInt()
true, 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
, чтобы сканер
продолжал выводить запросы до тех пор, пока не будет выполнено определенное условие.