1. ホーム
  2. java

[解決済み] InputMismatchExceptionでtry/catchすると、無限ループになる。

2022-02-01 10:23:31

質問

そこで、ユーザー入力からintを受け取るプログラムを作っています。非常に単純な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);
    }
}

2つ目の整数に0を入力すると、try/catchがその通りに実行され、もう一度入力させられます。しかし、5.5を入力してInputMismatchExceptionが発生した場合、エラーメッセージが表示され、無限ループに陥ります。なぜ、このようなことが起こるのでしょうか?また、どうすればよいのでしょうか?(ちなみに、catchの引数にInputMismatchExceptionを明示的に入力してみましたが、問題は解決されませんでした。

どうすればいいですか?

を呼び出す必要があります。 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 スキャナ

<ブロッククオート

スキャナがInputMismatchExceptionをスローした場合、スキャナは例外の原因となったトークンを渡さないので、他のメソッドで取得したりスキップしたりすることができるようになります。