扫描仪被跳过

时间:2018-06-13 20:42:14

标签: java java.util.scanner

我正试图从用户那里得到2个整数。这是我的代码的相关部分:

 public void play() {

        int row=0,col=0;
        initializeboard();
        printboard();

        do {

            currentPlayer = players.remove();  //Returns currentPlayer
            System.out.println("Ok, "+ currentPlayer.getname() + ", Enter your Move: Row[1-3] & Column[1-3]");
            Scanner choice = new Scanner(System.in);
            if (choice.hasNext()) {

                row = choice.nextInt();
                col = choice.nextInt();
                while (row<1 || row>3 || col<1 || col>3 || board[row-1][col-1] != '-' ) {
                    System.out.println("Well, Move is not Valid or has already Been Selected, Try Again :/");
                    row = choice.nextInt();
                    col = choice.nextInt();
                }
                choice.close();
            }

            board[row][col] = currentPlayer.getsign(); //Places Sign in Game Board
            printboard();
            System.out.println();
            players.append(currentPlayer); //Inserts the Next Player
        } while(!win() && !isFull());
}

首先,它会抛出NoSuchElementException,因此我使用了.hasNext()。现在,它只是跳过扫描仪并立即调用printboard()

3 个答案:

答案 0 :(得分:2)

问题是您正在使用相同的流创建并关闭多个Scanner对象。

Peter Lawrey在this post中的回答解释了为什么不应该从同一个流创建多个Scanner对象。以下是答案的引用:

  

关闭流后,它会关闭基础流,您无法再次使用它。如果要阻止再次使用它,请关闭System.in。

最好的方法是在程序中创建一个final Scanner对象(每个流),并在需要使用时将其传递给方法:

static final Scanner scan = new Scanner(System.in);

答案 1 :(得分:1)

问题在于:

do {
    Scanner choice = new Scanner(System.in);
    [...]
    choice.close();
} while (!win() && !isFull());

您正在循环中打开Scanner(第一个错误),但更重要的是,您正在关闭Scanner。 关闭Scanner也会关闭您使用的InputStream System.in。您无法再次打开该流,因此您将永远无法执行两次循环。

public void close()

  

如果此扫描程序尚未关闭,那么如果其底层可读也实现了Closeable接口,则将调用可读的close方法。

这实际上是你所面临的问题。关闭创建的第一个Scanner,然后尝试打开一个新的System.in,因为hasNext已关闭,因此无法读取值(!win() && !isFull()返回false)。并且您很可能进入无限循环,因为main将始终给出相同的结果。

我建议不要关闭它(在这种情况下,这并不总是坏事,因为它是一个局部变量,没有风险)。
或者只是在方法中使用一个参数来提供它(并且仍然没有在方法中关闭它)。让Scanner方法管理public void play(Scanner choice){ ... }

return cache[state];

答案 2 :(得分:0)

它可能抛出了 NoSuchElementException ,因为你没有输入整数。

它“跳过”Scanner的原因可能是因为所有hasNext评估都是System.in中是否包含String。因此,它会评估该表达式并返回truefalse。然后你的程序在while循环中计算表达式,可能会发现它是假的。然后最后继续并调用printboard

我建议您返回并将hasNext更改为

row = choice.nextInt();
col = choice.nextInt();

然后确保输入整数。