我这里有两个代码块。一个扫描仪正确等待用户输入,另一个扫描仪正好通过它并调用nextInt()
,返回NoSuchElementException
。这是有效的块:
public void startGame() {
out.println("Player1: 1 for dumb player, 2 for smart player, 3 for human player.");
Scanner scan = new Scanner(System.in);
p = scan.nextInt();
if (p == 1)
p1 = new DumbPlayer("ONE");
if (p == 2)
p1 = new SmartPlayer("ONE");
else
p1 = new HumanPlayer("ONE");
out.println("Player2: 1 for dumb player, 2 for smart player, 3 for human player.");
p = scan.nextInt();
if (p == 1)
p2 = new DumbPlayer("TWO");
if (p == 2)
p2 = new SmartPlayer("TWO");
else
p2 = new HumanPlayer("TWO");
scan.close();
以下是没有的块:
public int findBestMove(Set<Integer> moves, Board b) {
Set<Integer> set = new HashSet<Integer>();
out.println("Player " +name+ ", select a column from 1-7: ");
Scanner scan = new Scanner(System.in); <--here it should wait for input, but does not!
int move = scan.nextInt(); <-- NoSuchElementException
scan.close();
for (int x = 1; x <= 7; x++) {
set.add(move);
move += 7;
}
....etc
这两个都是单独的类,并且在另一个类中从main方法调用。基本上main()
调用startGame()
,后者又调用某些Player类的findBestMove()
方法...这是非工作代码所在的位置。在程序中是否有时候不适合接受输入?我的印象是,无论何时我想要用户输入,我都可以使用这种方法。谢谢!
答案 0 :(得分:6)
nextInt()
不会丢弃流中的\n
,因此下一个调用找不到任何内容。您必须使用Scanner.skip("\n")
或Scanner.nextLine()
编辑在确定“跳过readInt()
”后意味着代码引发了异常。在@Andreas的帮助下,这是另一种解决方案。在java6中,添加了一个新类Console,用于为stdin提供更好的接口。它会返回一个不关心你关闭它的读者。所以下面的代码段工作正常:
Scanner fi = new Scanner(System.console().reader());
System.out.println(fi.nextInt());
fi.close();
fi = new Scanner(System.console().reader());
System.out.println(fi.nextInt());
fi.close();
答案 1 :(得分:4)
根据java.util.Scanner javadoc,如果此流实现Scanner.close()
接口,Closeable
将关闭关联的流。 java.lang.System.in
是InputStream,它实现了Closeable
接口。因此,在与Scanner.close()
相关联的Scanner
上致电System.in
后,System.in
流已关闭且不再可用。
以下SSCCE适合我。我已从问题中删除了一些与实际问题无关的代码。请注意,使用此方法,虽然它有效,但Eclipse会向我发出警告"Resource leak: 'scan' is never closed"
,因此更好的解决方案是仅使用一个Scanner实例。
package com.example;
import java.util.Scanner;
import java.util.Set;
import static java.lang.System.out;
public class ScannerTest {
int p = 0;
String name = "Test";
public void startGame() {
out.println("Player1: 1 for dumb player, 2 for smart player, 3 for human player.");
Scanner scan = new Scanner(System.in);
p = scan.nextInt();
out.println("Result1: " + p);
out.println("Player2: 1 for dumb player, 2 for smart player, 3 for human player.");
p = scan.nextInt();
out.println("Result2: " + p);
// scan.close(); // Do not close the Scanner to leave System.in open
}
public int findBestMove(Set<Integer> moves, Object /*Board*/ b) {
out.println("Player " +name+ ", select a column from 1-7: ");
Scanner scan = new Scanner(System.in);
int move = scan.nextInt();
// scan.close(); // Do not close the Scanner to leave System.in open
out.println("Move: " + move);
return 0;
}
public void run() {
startGame();
findBestMove(null, null);
}
public static void main(String[] args) {
ScannerTest st = new ScannerTest();
st.run();
}
}
答案 2 :(得分:0)
尝试使用scan.reset();
代替scan.close()
。正如Denis Tulskiy所说,scan.close()
将抛出NoSuchElementException。
答案 3 :(得分:0)
我只花了大约15分钟来解决这个问题,我的问题与上述所有问题不同。
代码很好,但是我正在使用Sublime Text并在windows中的sublime文本中的终端模拟器中运行它。这阻止了扫描仪实际允许我尝试输入内容。
我使用cmd运行应用程序,它工作正常。我希望这有助于某人。