42

だから、私はこのコードで立ち往生しています:

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

public class ConsoleReader {

    Scanner reader;

    public ConsoleReader() {
        reader = new Scanner(System.in);
        //reader.useDelimiter(System.getProperty("line.separator"));
    }

    public int readInt(String msg) {
        int num = 0;
        boolean loop = true;

        while (loop) {
            try {
                System.out.println(msg);
                num = reader.nextInt();

                loop = false;
            } catch (InputMismatchException e) {
                System.out.println("Invalid value!");
            } 
        }
        return num;
    }
}

ここに私の出力があります:

整数を挿入してください:
無効な値です!
整数を挿入してください:
無効な値です!
...

4

5 に答える 5

70

Scannerのjavadocによると:

スキャナーが InputMismatchException をスローすると、スキャナーは例外の原因となったトークンを渡さないため、他の方法でトークンを取得またはスキップできます。

つまり、次のトークンが でない場合、がintスローされInputMismatchExceptionますが、トークンはそこにとどまります。したがって、ループの次の繰り返しで、reader.nextInt()同じトークンを再度読み取り、例外を再度スローします。必要なのは使い切ることです。reader.next()トークンを消費するには、内部に a を追加しcatchます。これは無効であり、破棄する必要があります。

...
} catch (InputMismatchException e) {
    System.out.println("Invalid value!");
    reader.next(); // this consumes the invalid token
} 
于 2010-08-26T05:18:59.300 に答える
0

私がすることは、Scanner.nextLine()を使用して行全体を読み取ることです。次に、返された文字列を読み取る別のスキャナーを作成します。

String line = reader.nextLine();
Scanner sc = new Scanner(line);

これにより、サンプル関数は次のようになります。

  public int readInt(String msg) {
        int num = 0;
        boolean loop = true;

        while (loop) {
            try {
                System.out.println(msg);
                String line = reader.nextLine();
                Scanner sc = new Scanner(line);
                num = sc.nextInt();   
                loop = false;
            } catch (InputMismatchException e) {
                System.out.println("Invalid value!");

            } 
        }
        return num;
    }

このようにして、入力を取得するスキャナーとそれを検証するスキャナーが1つずつあるため、リーダーが正しい形式の入力を入力したかどうかをリーダーが気にする必要はありません。

于 2010-08-26T05:29:08.107 に答える
0

while-doのガードは'loop'変数です。

コードが割り当てループに到達する前にスローされる例外自体=false; 正確には、例外はnum = reader.nextInt();である前のステートメントでスローされます。

例外がスローされると、「loop」変数の値は「true」になりますが、コードはcatchブロックにジャンプして、while-doを繰り返します。このwhile-doは、次の反復で再び例外がスローされたり、ブロックをキャッチするためにジャンプしたりするため、停止することはありません。

このwhile-doを終了するには、while-doを次のような別の論理的なもので保護する必要があります。

  1. リーダーが非整数文字を取得したら終了します
  2. EOFで終了

これは、catchブロックまたは他のいくつかの行で実行できます。ただし、正確な解決策は仕様によって異なります。

于 2010-08-26T05:34:00.200 に答える
0

これを試すこともできます:

   public int readInt(String msg) {
        int num = 0;
        try {
            System.out.println(msg);
            num = (new Scanner(System.in)).nextInt();
        } catch (InputMismatchException e) {
            System.out.println("Invalid value!");
            num = readInt(msg);
        } 
        return num;
    }
于 2010-08-26T05:34:48.967 に答える