有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么多个nextInt()可以工作?

在下面的Java代码中

Scanner input = new Scanner(System.in);    //Cmd1
int i1,i2;                                 //Cmd2
i1 = input.nextInt();                      //Cmd3
System.out.println("value of i1 is "+ i1); //Cmd4
i2 = input.nextInt();                      //Cmd5
System.out.println("value of i2 is "+ i2); //Cmd6
String s1;                                 //Cmd7
input.nextLine();                          //Cmd8
s1 = input.nextLine();                     //Cmd9
System.out.println("value of s1 is "+ s1); //Cmd10

我在控制台中获得了以下输出

<myinput> 1
<output>  value of i1 is 1
<myinput> 2
<output>  value of i2 is 2
<myinput> firstString
<output>  value of s1 is firstString

<;myinput>;一直等待输入,直到我按下enter键。我尝试了tab,多次tabspace,但它一直在等待,没有移动到下一个命令<;产量>;因此,我假设nextInt会等到它在输入流中找到\n后再转到下一个命令

查看来自Scanner is skipping nextLine() after using next() or nextFoo()?的答案,我们必须添加Cmd8的原因是,nextInt()继续读取输入,直到\n,将输入发送到程序并将\n放回输入流的前面。现在,当“Cmd8”中的nextLine()开始读取它时,它在输入流的开始处发现\n,没有任何前面的字符串,它假定用户没有输入任何内容,因此将空字符串作为输入并转到Cmd9

我的疑问是,因为nextInt()也读取till\n(根据我的经验,这意味着Cmd3一直在等待,直到我按下enter),为什么Cmd5在等待我的输入。它还应该在输入流的开头找到\n,并假设我没有输入任何内容,并将空整数作为输入(类似于Cmd8的行为)。这里发生了什么


共 (2) 个答案

  1. # 1 楼答案

    我已经通过调试JRE Scanner类方法分析了您的问题。当您调用nextInt函数时,扫描器会查看当前缓冲区。如果没有可用的输入,则开始监听键盘,直到按Enter键,整个键盘字符追加到缓冲区,并尝试匹配它是否为整数。当找到它时,整数nextInt返回值并递增缓冲区的位置索引。下一步,您再次调用了nextInt,并且只有\n字符,然后丢弃它并等待下一个整数模式。此外,缓冲区的下一个字符也是\n。调用nextLine时,它会查看缓冲区并打印空行。所以第二个nextLine是从空文本开始的

    也许这会让人困惑。让我们看一下场景:

    注意:索引^表示缓冲区的读取位置


    1. 台阶
    i1 = input.nextInt();
    
    keyboard = 1 2 {Enter}
    buffer = | 1 | 2 | \n |
    index  =   ^
    

    返回12,下一个缓冲区位置位于\n


    1. 台阶
    i2 = input.nextInt();
    
    keyboard = 3 4 {Enter}
    buffer = | 1 | 2 | \n | 3 | 4 | \n |
    index  =           ^
    

    返回34,下一个缓冲区位置位于第二个\n


    1. 台阶
    input.nextLine();
    

    缓冲区具有\n字符,所以扫描仪不会等待键盘并返回值

    buffer = | 1 | 2 | \n | 3 | 4 | \n |
    index  =                         ^
    

    返回empty text


    1. 台阶
    s1 = input.nextLine();
    
    keyboard = test {Enter}
    buffer = | 1 | 2 | \n | 3 | 4 | \n | t | e | s | t | \n |
    index  =                             ^
    

    返回test


  2. # 2 楼答案

    请注意^{}文件中的以下摘录:

    Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern.

    Scanner使用的默认分隔符是\p{javaWhitespace}+,您可以通过以下方式获得:

    import java.util.Scanner;
    
    public class Main {
        public static void main(String... args) {
            Scanner input = new Scanner(System.in);
            System.out.println(input.delimiter());
        }
    }
    

    下面的代码行显示了在找到10hello时如何找到完整的标记,即,无论您按多少次Enternext()nextInt()等都会一直请求输入,直到输入非空白字符注意:在nextInt()的情况下,值10可解析为int,但hello不可解析,因此InputMismatchException将被抛出

    public class Main {
        public static void main(String... args) {
            System.out.println(Character.isWhitespace('\n'));
            System.out.println("\n\n\n\n\n".split("\\p{javaWhitespace}+").length);
            System.out.println("10\n".split("\\p{javaWhitespace}+").length);
            System.out.println("hello\n".split("\\p{javaWhitespace}+").length);
        }
    }
    

    输出:

    true
    0
    1
    1
    

    这适用于所有{},但{}除外,其{a2}(下面给出的摘录)非常清楚其行为与其他{}不同

    Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line. Since this method continues to search through the input looking for a line separator, it may buffer all of the input searching for the line to skip if no line separators are present.

    换句话说,nextLine()将捕获所有内容,包括直接输入的空白字符或先前输入的剩余字符