2

この単純なコードを書いて、double を取得し、double が与えられるまで尋ね続けますが、文字列を与えると無限ループになり、その理由がわかりません。このように動作する理由は何ですか?

Scanner scanner = new Scanner(System.in);   
double x = 0.0d;

while (true) {
    try {
        System.out.println("Gimme a double:");

        x = scanner.nextDouble();
        break;
    } catch (InputMismatchException e) {}           
}

System.out.println(x);
4

3 に答える 3

7

最初に無効なdouble値を入力すると無限ループになります。その後、制御は例外ブロックに入ります。Scanner#nextDoubleは改行文字を消費しないため、これらの値は繰り返しステートメントに渡されます。

x = scanner.nextDouble();

すでに入力を受け取っていることをブロックしません。これにより、無限ループが発生します。

空の例外ブロックを使用するのではなくScanner#nextLine、改行文字を消費するために使用する必要があります。

} catch (InputMismatchException e) {
    System.out.println("Error found: " + scanner.nextLine() + " continuing...");
}

次の繰り返しでScanner#nextDouble行がブロックされるようにします。IO

于 2013-05-01T00:03:44.427 に答える
2

の javadocs によると、 への変換が成功しなかったScanner#nextDouble場合、文字は消費されdoubleません (ただし、変換が成功した場合は消費されます)。

入力の次のトークンを double としてスキャンします。次のトークンを有効な double 値に変換できない場合、このメソッドは InputMismatchException をスローします。変換が成功すると、スキャナは一致した入力を超えて進みます。

プログラムの出力例:

$ java Main
Gimme a double:
3.5
3.5
$ java Main
Gimme a double:
blah
Gimme a double:
Gimme a double:
Gimme a double:
Gimme a double:
Gimme a double:
Gimme a double:
(Infinite loop here)

できれば例外ハンドラで、文字を自分で消費する必要があります。

} catch (InputMismatchException e) {
    System.out.println("Not a double: " + scanner.nextLine());
}

変更されたプログラムの出力例:

$ java Main
Gimme a double:
blah
Skipped Past: blah
Gimme a double:
3.56
3.56
于 2013-05-01T00:10:02.920 に答える
1

Reimeus は、無限ループが発生する理由を正しく述べています。scanner.nextLine()catch ブロックを呼び出して修正できます。

public static void main(String[] args) throws IllegalArgumentException,
        IllegalAccessException {
    /*
     * StackTest t = new StackTest();
     * 
     * for(Field f :t.getClass().getDeclaredFields()){
     * System.out.println(f.get(t)); }
     */

    Scanner scanner = new Scanner(System.in);
    double x = 0.0d;

    while (true) {
        try {
            System.out.println("Gimme a double:");

            x = scanner.nextDouble();
            break;
        } catch (InputMismatchException e) {
            scanner.nextLine();
        }
    }

    System.out.println(x);
}
于 2013-05-01T00:08:00.067 に答える