读取 Int 时从缓冲区获取字符

问题描述 投票:0回答:1

我正在构建一个语言解释器,需要有两个函数,一个用于输入整数,另一个用于输入字符(来自 System.in)。例如输入整数-字符-整数-字符-字符-字符来自

123 C
456
DEF

应给出

123
C
456
D
E
F

在我当前的实现中,我可以获取

123
C
456
D
(通过耗尽当前输入行)或获取
123
C
456
E
,
F
(跳过行首的任何字符)。

我的代码是:

class Variable extends Var {
    private static Scanner scanner = new Scanner(System.in);
    private static String buffer = ""; // Buffer to hold unprocessed characters
    private static int bufferIndex = 0; // Index to track the next character in the buffer
    private String name;

    public Variable(String name) {
        this.name = name;
    }

    public String getName(HashMap<String, Integer> values) {
        return name;
    }

    public int evaluate(HashMap<String, Integer> values) {
        if (name.equals("read")) {
            return scanner.nextInt();
        }
        if (name.equals("get")) {
            // Refill buffer if empty or fully processed
            while (bufferIndex >= buffer.length()) {
                    buffer = scanner.nextLine();
                    bufferIndex = 0; // Reset the index for the new buffer
            }
            // Return the ASCII value of the next character in the buffer
            return (int) buffer.charAt(bufferIndex++);
        }
        return values.getOrDefault(name, 0);
    }
}
java input io user-input inputstream
1个回答
0
投票

扫描仪是最不适合这项工作的工具。或者,至少,你使用它的方式。

Scanner 是将输入分离为标记并返回这些标记的东西。标记被定义为“分隔符之间的内容”,分隔符默认设置为“任意数量的空格”。

你想要的是一个时髦的分隔符:“2个字符之间任意数量的空格,包括根本没有空格,但2个数字之间至少有1个空格”。

这会让你陷入奇特的正则表达式中,除非你非常熟悉它们,否则它们是不可读的。

如果你跳过所有这些并找到另一种方法来做到这一点,你会学到更多。例如,只抓取单个字符。只有当你获取的字符是数字并且前一个字符也是数字时,才将它们组合成一个新数字,否则,你得到了一个令牌。

忘记

Scanner
,无论如何,它从来都不是用于键盘输入的。

class MyApp {
  public static void main(String[] args) throws IOException {
    new MyApp().go();
  }

  StringBuilder token = new StringBuilder();

  void go() throws IOException {
    while (true) {
      int v = System.in.read();
      if (v == -1) {
        cycleToken();
        return;
      }
      
      char w = (char) v;
      if (w >= '0' && w <= '9') {
        token.append(w);
      } else {
        cycleToken();
        token.append(w);
        cycleToken();
      }
    }
  }

  void cycleToken() {
    String z = token.toString().trim();
    if (!z.isEmpty()) System.out.println("TOKEN: " + z);
    token.setLength(0);
  }
}
  • StringBuilder
    是一个可变字符串。我们在这里需要它来添加数字;在看到非数字或输入结束之前,我们不知道何时“完成”数字。
  • 任何非数字都可以立即作为代币发出;仅“保存”数字以便稍后发出,因为接下来可能会出现另一个数字。
© www.soinside.com 2019 - 2024. All rights reserved.