Java:在第一个令牌后停止扫描程序

时间:2014-04-29 20:26:04

标签: java string stream

我尝试为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只是从流中读取了太多数据。

实际上,我看到了一些可能的方法:

  1. 在输入中放置标记,以防止扫描仪进一步读取。

  2. 扩展ByteArrayInputStream,使其每次尝试只显示一个令牌。这可能意味着操纵可用()方法的输出,pos属性和流的buf内容,以及跟踪扫描仪执行的读数的数量。尽管如此,无论应该读取多少令牌,扫描仪都会不断询问数据。有人这么做过吗?

  3. 使用提供2下(或类似内容)所述功能的其他Stream。

  4. 要求学生使用不同的方法(而不是nextInt)从扫描仪中读取数据。有这样的方法吗?我找不到一个。

  5. 我已经开始通过扩展ByteArrayInputStream来操纵行为,但并没有因为我认为这可能是一个概念上太复杂的方法而走得太远。

    感谢任何帮助。

    祝你好运, 托马斯

2 个答案:

答案 0 :(得分:0)

首次阅读后尝试关闭第一台扫描仪。这应该关闭第一台扫描仪并允许第二台扫描仪读取下一个变量。

答案 1 :(得分:0)

我认为答案是......不。

没有办法阻止Scanner提前读取和缓冲字符,也没办法强制它放弃"放回"它已缓冲的字符。 (实际上,除非您正在阅读的源代码支持标记/重置或推回方法,否则将无法"放回"字符。)

您需要重新考虑您的测试方法。重用Scanner实例。

另一种选择是实施您自己的Scanner版本......这样做可以让您放弃"放回"不知怎的,缓冲的字符。