Java 扫描器 while 循环

Java Scanner while loop

我正在尝试接受一个字符串输入,该字符串输入由多行数字组成,由“,”和“;”分隔.

示例:

1,2;3,4;5,6;
9,8;7,6;
0,1;
;

代码:

ArrayList<Integer> alist = new ArrayList<>();
        String delims = ";|\,";
        int i = 0;
        Scanner input = new Scanner(System.in);
        input.useDelimiter(delims);
        while (input.hasNext()) {
            alist.add(i, input.nextInt());
            System.out.print(i + ' ');
            System.out.print(alist.get(i) + '\n');
            i++;
        }
        System.out.print('x');

当我在 eclipse 中 运行 时:

1,2;3,4;5,6;    ( <= what i typed in console)
321133123413351436153716    ( <= output)                

我期待更像:

0 1
1 2
2 3
3 4
4 5 
5 6
x

为什么我会得到这种输出?

一个问题是 System.in 基本上是一个无限流:hasNext 将始终 return 为真,除非用户输入一个特殊的命令来关闭它。

所以你需要让用户输入一些东西来告诉你他们已经完成了。例如:

while(input.hasNext()) {
    System.out.print("Enter an integer or 'end' to finish: ");
    String next = input.next();
    if("end".equalsIgnoreCase(next)) {
        break;
    }

    int theInt = Integer.parseInt(next);
    ...

对于您的程序,您尝试解析的输入可能以您检查的 1,2;3,4;5,6;end1,2;3,4;5,6;# 等特殊字符结尾。

并在这些行中:

System.out.print(i + ' ');
System.out.print(alist.get(i) + '\n');

您似乎在尝试执行 String 连接,但由于 char 是数字类型,因此它执行的是加法。这就是为什么你会得到疯狂的输出。所以你需要使用 String 而不是 char:

System.out.print(i + " ");
System.out.print(alist.get(i) + "\n");

或者只是:

System.out.println(i + " " + alist.get(i));

编辑评论。

例如,您可以使用 nextLine 从带有默认分隔符的 Scanner 中提取输入,然后创建第二个 Scanner 来扫描该行:

Scanner sysIn = new Scanner(System.in);
while(sysIn.hasNextLine()) {
    String nextLine = sysIn.nextLine();
    if(nextLine.isEmpty()) {
        break;
    }

    Scanner lineIn = new Scanner(nextLine);
    lineIn.useDelimiter(";|\,");

    while(lineIn.hasNextInt()) {
        int nextInt = lineIn.nextInt();
        ...
    }
}

由于 Radiodef 已经回答了你的实际问题(" 而不是 '),这里有一些我认为可能对你有帮助的建议(这更像是评论而不是答案, 但对于实际评论来说太长了):

当您使用 Scanner 时,尝试将 hasNextX 函数调用与 nextX 调用相匹配。 IE。在你的情况下,使用 hasNextIntnextInt。这使得您在意外输入时获得异常的可能性大大降低,同时还可以通过键入另一个分隔符轻松结束输入。

扫描器 useDelimiter 调用 returns 扫描器,因此它可以链接起来,作为扫描器初始化的一部分。 IE。你可以写:

Scanner input = new Scanner(System.in).useDelimiter(";|\,");

当您添加到 ArrayList 的末尾时,您不需要(通常也不应该)指定索引。

int i = 0,i++是for循环的教科书例子。仅仅因为您的测试语句不涉及 i 并不意味着您不应该使用 for 循环。

你的代码,加上以上几点,变成如下:

ArrayList<Integer> alist = new ArrayList<>();
Scanner input = new Scanner(System.in).useDelimiter(";|\,");
for (int i = 0; input.hasNextInt(); i++) {
    alist.add(input.nextInt());
    System.out.println(i + " " + alist.get(i));
}
System.out.println('x');

编辑:不得不提到我最喜欢的 Scanner 分隔符之一,因为它在这里非常合适:

Scanner input = new Scanner(System.in).useDelimiter("\D");

这将使扫描器仅覆盖数字,拆分任何非数字的内容。与 hasNextInt 结合使用时,它还会在从终端输入读取时在第一个空白行结束输入。