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;end
或 1,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。在你的情况下,使用 hasNextInt
和 nextInt
。这使得您在意外输入时获得异常的可能性大大降低,同时还可以通过键入另一个分隔符轻松结束输入。
扫描器 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
结合使用时,它还会在从终端输入读取时在第一个空白行结束输入。
我正在尝试接受一个字符串输入,该字符串输入由多行数字组成,由“,”和“;”分隔.
示例:
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;end
或 1,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。在你的情况下,使用 hasNextInt
和 nextInt
。这使得您在意外输入时获得异常的可能性大大降低,同时还可以通过键入另一个分隔符轻松结束输入。
扫描器 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
结合使用时,它还会在从终端输入读取时在第一个空白行结束输入。