问题描述
@Test
public void testBattle() throws IOException{
String input = "go forward\ngo left\ntake Pointy Stick\ngo backward\ngo " +
"right\nnormal attack\nnormal attack\nquit\n";
provideInput(input);
actual = new File("src/main/testFiles/testBattle.txt");
expected = new File("src/main/testFiles/testBattleExpected.txt");
PrintStream o = new PrintStream(actual);
System.setout(o);
ui.gameLoop();
assertTrue(FileUtils.contentEqualsIgnoreEOL(actual,expected,null));
}
这是提供输入法:
private void provideInput(String data) {
String newdata = data.trim();
testIn = new ByteArrayInputStream(newdata.getBytes());
System.setIn(testIn);
}
我正在做下一行扫描仪,所以:
command = input.nextLine().toLowerCase().trim();
其中“输入”在这里代表扫描仪对象 但是我仍然遇到此错误,特别是在第一个“正常攻击”传递到system.in
时java.util.NoSuchElementException: No line found
在上面那一行。我以为nextline忽略了空格?如果不是我设置的字符串格式错误,则不包含它?
编辑: 在UI.gameLoop()的前几行中,我只初始化了一次扫描程序。
public void gameLoop() throws IOException,JsonSyntaxException {
input = new Scanner(system.in);
engine = new GameEngine(path);
解决方法
我以为nextline忽略了空格?
不。根据{{3}},它会读取下一个行尾序列(或EOF),然后返回直到(但不包括)行尾序列的所有内容。
如果您得到
java.util.NoSuchElementException: No line found
这意味着Scanner
已经到达输入流的末尾,或者(也许)Scanner
正在尝试从过早的输入流中读取关闭了代码中的其他地方。
我们可以猜测出真正的问题是什么,但是如果不看>> your javadocs,我们将无法走得更远。
实际上,我只是发现了一个线索:
...我正在用JUnit进行测试...
这可能是您问题的根源。 JVM在其生存期内只能“读取到System.in
的末尾”一次。如果您有两个或多个需要执行此操作的JUnit测试,这将很困难,除非您找到一种方法来“模拟” System.in
变量。
重组代码可能更简单,以便您从某个流中获取输入作为参数传递给游戏代码。通过重组,您可以更轻松地编写单元测试。
,没有太多的事情要做,但是我猜您正在创建多个扫描仪,每次要读取一行时就创建一个。由于人类是慢打字员,因此通常可以交互地正常工作,但是当每个扫描程序的预读最终消耗了多行时,此操作将失败。
您可以看到此MCVE中的区别:
import java.util.*;
import java.io.*;
class Foo {
public static void main(String[] args) throws Exception {
String newdata = "go forward\ngo left\ntake Pointy Stick\ngo backward\ngo " +
"right\nnormal attack\nnormal attack\nquit\n".trim();
ByteArrayInputStream testIn = new ByteArrayInputStream(newdata.getBytes());
System.setIn(testIn);
boolean includeBug = Boolean.valueOf(args[0]);
if (includeBug) {
for(int i=0; i<8; i++) {
Scanner input = new Scanner(System.in);
System.out.println("Read: " + input.nextLine());
}
} else {
Scanner input = new Scanner(System.in);
for(int i=0; i<8; i++) {
System.out.println("Read: " + input.nextLine());
}
}
}
}
当includeBug
为true时,它将为每行创建一个新的Scanner并崩溃,如您所说。如果为假,它将创建一个扫描仪并正常工作:
$ javac Foo.java
$ java Foo true
Read: go forward
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at Foo.main(Foo.java:17)
$ java Foo false
Read: go forward
Read: go left
Read: take Pointy Stick
Read: go backward
(etc)
,
您是否要检查下一行?使用扫描仪,通常要么必须处理异常(不是我真正喜欢的异常),要么必须使用hasNextLine()方法来避免异常。
while (input.hasNextLine()) {
command = input.nextLine().toLowerCase().trim();
}