Как я мешаю Сканеру выдавать исключения, когда неправильный тип вводится?

Вот некоторый пример кода:

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 или подсказкой ре с, "Сколько вторгается?" Я хотел бы знать, как сделать оба из них.

13
задан Laurel 9 May 2016 в 23:41
поделиться

3 ответа

Для предварительной проверки можно использовать один из многих методов 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
18
ответ дан 1 December 2019 в 22:38
поделиться

Вообще, мне очень, очень не нравится использовать один и тот же вызов библиотеки и для чтения, и для парсинга. Языковые библиотеки кажутся очень негибкими и часто просто не могут быть подстроены под вашу волю.

Первый шаг, который извлекает данные из System.in, не должен быть неудачным, поэтому пусть он прочитает их как строку в переменную, затем преобразует строковую переменную в int. Если преобразование не удалось, отлично - выведите ошибку и продолжайте.

Когда вы оборачиваете свой поток чем-то, что может выбросить исключение, становится непонятно, в каком состоянии весь этот беспорядок оставляет ваш поток.

2
ответ дан 1 December 2019 в 22:38
поделиться

Всегда полезно иметь , что ваше приложение выдает ошибку при возникновении ошибки, в отличие от способов предотвращения ее возникновения .

Один из альтернативных вариантов - заключить код в блок try {...} catch {...} для InputMismatchException . Вы можете также хотите заключить код в цикл while , чтобы сканер продолжал выводить запросы до тех пор, пока не будет выполнено определенное условие.

1
ответ дан 1 December 2019 в 22:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: