简体   繁体   English

Java Scanner while循环

[英]Java Scanner while loop

I'm trying to take in a string input which consists of multiple lines of numbers separated by ',' and ';' 我正在尝试输入由多行数字组成的字符串输入,这些数字行之间用','和';'分隔 .

Example: 例:

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

Code: 码:

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');

When I run this in eclipse: 当我在Eclipse中运行时:

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

I'd expect something more like: 我希望有更多类似的东西:

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

Why am I getting this sort of output? 为什么我得到这种输出?

One problem is that System.in is basically an infinite stream: hasNext will always return true unless the user enters a special command that closes it. 一个问题是System.in是无限流:除非用户输入关闭它的特殊命令,否则hasNext将始终返回true。

So you need to have the user enter something that tells you they are done. 因此,您需要让用户输入一些内容来告诉您已完成操作。 For example: 例如:

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);
    ...

For your program, you might have the input you are trying to parse end with a special character like 1,2;3,4;5,6;end or 1,2;3,4;5,6;# that you check for. 对于您的程序,您可能想要解析的输入以特殊字符结束,例如1,2;3,4;5,6;end1,2;3,4;5,6;#对于。

And on these lines: 在这些行上:

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

It looks like you are trying to perform String concatenation but since char is a numerical type, it performs addition instead. 看起来您正在尝试执行String串联,但是由于char是数字类型,因此它执行加法运算。 That is why you get the crazy output. 这就是为什么您会得到疯狂的输出。 So you need to use String instead of char : 因此,您需要使用String而不是char

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

Or just: 要不就:

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

Edit for comment. 编辑以发表评论。

You could, for example, pull the input using nextLine from a Scanner with a default delimiter, then create a second Scanner to scan the line: 例如,您可以使用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();
        ...
    }
}

Since Radiodef has already answered your actual problem( " instead of ' ), here are a few pointers I think could be helpful for you(This is more of a comment than an answer, but too long for an actual comment): 由于Radiodef已经回答了您的实际问题( "而不是“ ' ),因此,我认为这对您有帮助(这里的注释多于评论而不是答案,但对于实际的评论来说太长了):

When you use Scanner, try to match the hasNextX function call to the nextX call. 当您使用Scanner时,请尝试使hasNextX函数调用与nextX调用匹配。 Ie in your case, use hasNextInt and nextInt . 即在您的情况下,使用hasNextIntnextInt This makes it much less likely that you will get an exception on unexpected input, while also making it easy to end input by just typing another delimiter. 这使得您在意外输入时遇到异常的可能性大大降低,同时通过键入另一个定界符也很容易结束输入。

Scanners useDelimiter call returns the Scanner, so it can be chained, as part of the initialisation of the Scanner. 扫描程序的useDelimiter调用返回扫描程序,因此可以将其链接起来,作为扫描程序初始化的一部分。 Ie you can just write: 即,您可以只写:

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

When you add to the end of an ArrayList, you don't need to(and usually should not) specify the index. 当您添加到ArrayList的末尾时,不需要(通常不应)指定索引。

int i = 0 , i++ is the textbook example of a for loop. int i = 0i++是for循环的教科书示例。 Just because your test statement doesn't involve i does not mean you should not use a for loop. 仅仅因为您的测试语句不涉及i ,并不意味着您不应该使用for循环。

Your code, with the above points addressed becomes as follows: 解决了以上几点的代码如下:

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');

Edit: Just had to mention one of my favorite delimiters for Scanner, since it is so suitable here: 编辑:只需提及我最喜欢的Scanner分隔符之一,因为它在这里非常合适:

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

This will make a Scanner over just numbers, splitting on anything that is not a number. 这将使扫描仪仅扫描数字,分割除数字以外的任何内容。 Combined with hasNextInt it also ends input on the first blank line when reading from terminal input. hasNextInt结合使用时,在从端子输入读取时,它也会在第一个空白行上结束输入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM