我尝试为System.in生成自动输入,并希望能够在任意时间通过不同的扫描程序读取流中的后续标记:
// save System.in for later restoration
InputStream inTemp = System.in;
// create an input
String input = "15 3";
// push input into InputStream
InputStream bais = new ByteArrayInputStream(input.getBytes());
// deviate System.in
System.setIn(bais);
Scanner s1 = new Scanner(System.in);
// the nextInt should only read the "15" from the input
int i1 = s1.nextInt();
System.out.println("#1: " + i1 * 2);
Scanner s2 = new Scanner(System.in);
// the nextInt should read the "3" from the input
int i2 = s2.nextInt();
System.out.println("#2: " + i2 * 2);
// restore System.in
System.setIn(inTemp);
不幸的是,Scanner s1会预防性地读取流的整个内容,而不是只读取第一个令牌。因此,第二个扫描仪s2找到一个空输入。
上面的代码是对实际情况的极端简化:使用扫描仪的部分不在我的责任范围内。它是由将课程提交到考试系统的学生创建的。我们的系统调用学生们的语言。用测试数据填充System.in后的方法。因此,我们无法影响扫描仪的使用方式。顺便说一句:关闭扫描仪不会有帮助。第一个Scanner只是从流中读取了太多数据。
实际上,我看到了一些可能的方法:
在输入中放置标记,以防止扫描仪进一步读取。
扩展ByteArrayInputStream,使其每次尝试只显示一个令牌。这可能意味着操纵可用()方法的输出,pos属性和流的buf内容,以及跟踪扫描仪执行的读数的数量。尽管如此,无论应该读取多少令牌,扫描仪都会不断询问数据。有人这么做过吗?
使用提供2下(或类似内容)所述功能的其他Stream。
要求学生使用不同的方法(而不是nextInt)从扫描仪中读取数据。有这样的方法吗?我找不到一个。
我已经开始通过扩展ByteArrayInputStream来操纵行为,但并没有因为我认为这可能是一个概念上太复杂的方法而走得太远。
感谢任何帮助。
祝你好运, 托马斯
答案 0 :(得分:0)
首次阅读后尝试关闭第一台扫描仪。这应该关闭第一台扫描仪并允许第二台扫描仪读取下一个变量。
答案 1 :(得分:0)
我认为答案是......不。
没有办法阻止Scanner
提前读取和缓冲字符,也没办法强制它放弃"放回"它已缓冲的字符。 (实际上,除非您正在阅读的源代码支持标记/重置或推回方法,否则将无法"放回"字符。)
您需要重新考虑您的测试方法。重用Scanner
实例。
另一种选择是实施您自己的Scanner
版本......这样做可以让您放弃"放回"不知怎的,缓冲的字符。