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

StackOverflow https://stackoverflow.com/questions/2496239

Вопрос

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

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 Продолжайте подсказывать, пока не будет выполнено определенное состояние.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top