try / catch с InputMismatchException создает бесконечный цикл

java exception

91972 просмотра

7 ответа

4934 Репутация автора

Итак, я создаю программу, которая берет целые числа из пользовательского ввода. У меня есть очень простой блок try / catch, который, если пользователь не вводит int, должен повторять этот блок до тех пор, пока он не сделает это. Вот соответствующая часть кода:

import java.util.InputMismatchException;
import java.util.Scanner;


public class Except {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        boolean bError = true;
        int n1 = 0, n2 = 0, nQuotient = 0;

        do {
            try {
                System.out.println("Enter first num: ");
                n1 = input.nextInt();
                System.out.println("Enter second num: ");
                n2 = input.nextInt();
                nQuotient = n1/n2;
                bError = false;
            } 
            catch (Exception e) {
                System.out.println("Error!");
            }
        } while (bError);

        System.out.printf("%d/%d = %d",n1,n2, nQuotient);
    }
}

Если я введу 0 для второго целого числа, то try / catch сделает именно то, что должно, и заставит меня вставить его снова. Но если у меня есть InputMismatchException, например, при вводе 5.5 для одного из чисел, оно просто показывает мое сообщение об ошибке в бесконечном цикле. Почему это происходит, и что я могу с этим поделать? (Кстати, я попытался явно ввести InputMismatchException в качестве аргумента для перехвата, но это не решило проблему.

Автор: limp_chimp Источник Размещён: 03.10.2012 04:50

Ответы (7)


30 плюса

16883 Репутация автора

Решение

Вам нужно позвонить, next();когда вы получите ошибку. Также желательно использоватьhasNextInt()

       catch (Exception e) {
            System.out.println("Error!");
           input.next();// Move to next other wise exception
        }

Перед чтением целочисленного значения необходимо убедиться, что оно есть у сканера. И вам не понадобится такая обработка исключений.

    Scanner scanner = new Scanner(System.in);
    int n1 = 0, n2 = 0;
    boolean bError = true;
    while (bError) {
        if (scanner.hasNextInt())
            n1 = scanner.nextInt();
        else {
            scanner.next();
            continue;
        }
        if (scanner.hasNextInt())
            n2 = scanner.nextInt();
        else {
            scanner.next();
            continue;
        }
        bError = false;
    }
    System.out.println(n1);
    System.out.println(n2);

Javadoc of Scanner

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

Автор: Amit Deshpande Размещён: 03.10.2012 04:52

1 плюс

30339 Репутация автора

Поскольку bError = falseоператор никогда не достигается в try blockоператоре и оператор попадает в введенный ввод , он продолжает печатать ошибку в бесконечном цикле .

Попробуйте использовать это таким образом, используя hasNextInt()

catch (Exception e) {
            System.out.println("Error!");
           input.hasNextInt();         
        }

Или попробуйте использовать в nextLine()сочетании с Integer.parseInt()для получения ввода ....

Scanner scan = new Scanner(System.in);

int num1 = Integer.parseInt(scan.nextLine());
int num2 = Integer.parseInt(scan.nextLine());
Автор: Kumar Vivek Mitra Размещён: 03.10.2012 05:02

1 плюс

2596 Репутация автора

Чтобы дополнить ответ AmitD:

Просто скопируйте / вставьте вашу программу и получите такой вывод:

Error!
Enter first num: 
.... infinite times ....

Как видите, инструкция:

n1 = input.nextInt();

Постоянно выбрасывает Исключение, когда вводится ваше двойное число, и это потому, что ваш поток не очищен. Чтобы это исправить, следуйте ответу AmitD.

Автор: Hernan Velasquez Размещён: 03.10.2012 05:03

1 плюс

2084 Репутация автора

@Limp, ваш ответ правильный, просто используйте .nextLine () при чтении ввода. Образец кода:

    do {
        try {
            System.out.println("Enter first num: ");
            n1 = Integer.parseInt(input.nextLine());
            System.out.println("Enter second num: ");
            n2 = Integer.parseInt(input.nextLine());
            nQuotient = n1 / n2;
            bError = false;
        } catch (Exception e) {
            System.out.println("Error!");
        }
    } while (bError);

    System.out.printf("%d/%d = %d", n1, n2, nQuotient);

Прочитайте описание причины этой проблемы в ссылке ниже. Ищите ответ, который я отправил для деталей в этой теме. Проблема пользовательского ввода Java Homework

Хорошо, я кратко опишу это. Когда вы читаете ввод с помощью nextInt (), вы просто читаете числовую часть, но символ ENDLINE все еще был в потоке. Это было главной причиной. Теперь посмотрите на приведенный выше код, все, что я сделал, это прочитал всю строку и проанализировал ее, она по-прежнему выдает исключение и работает так, как вы ожидали, что он будет работать. Остальная часть вашего кода работает нормально.

Автор: Jimmy Размещён: 03.10.2012 05:04

4 плюса

774 Репутация автора

Вы также можете попробовать следующее

   do {
        try {
            System.out.println("Enter first num: ");
            n1 = Integer.parseInt(input.next());

            System.out.println("Enter second num: ");
            n2 = Integer.parseInt(input.next());

            nQuotient = n1/n2;

            bError = false;
        } 
        catch (Exception e) {
            System.out.println("Error!");
            input.reset();
        }
    } while (bError);
Автор: Debobroto Das Размещён: 03.10.2012 05:09

2 плюса

21 Репутация автора

другой вариант - определить вход сканера = новый сканер (System.in); внутри блока try это создаст новый объект каждый раз, когда вам нужно будет повторно ввести значения.

Автор: ron17ro Размещён: 29.07.2014 11:47

2 плюса

21 Репутация автора

Чтобы следовать ответу Debobroto Das вы также можете поставить после

input.reset();
input.next(); 

У меня была такая же проблема и когда я попробовал это. Это полностью исправило это.

Автор: YoMama420 Размещён: 19.11.2016 07:53
Вопросы из категории :
32x32