Skip to main content
Engineering LibreTexts

11.10: The Scanner Bug

  • Page ID
    17728
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    Now that you’ve had some experience with Scanner, there is an unexpected behavior we want to warn you about. The following code fragment asks users for their name and age:

    System.out.print("What is your name? ");
    name = in.nextLine();
    System.out.print("What is your age? ");
    age = in.nextInt();
    System.out.printf("Hello %s, age %d\n", name, age);
    

    The output might look something like this:

    Hello Grace Hopper, age 45
    

    When you read a String followed by an int, everything works just fine. But when you read an int followed by a String, something strange happens.

    System.out.print("What is your age? ");
    age = in.nextInt();
    System.out.print("What is your name? ");
    name = in.nextLine();
    System.out.printf("Hello %s, age %d\n", name, age);
    

    Try running this example code. It doesn’t let you input your name, and it immediately displays the output:

    What is your name? Hello , age 45 

    To understand what is happening, you have to understand that the Scanner doesn’t see input as multiple lines, like we do. Instead, it gets a “stream of characters” as shown in Figure 3.10.1.

    A stream of characters as seen by a Scanner.
    Figure \(\PageIndex{1}\): A stream of characters as seen by a Scanner.

    The arrow indicates the next character to be read by Scanner. When you call nextInt, it reads characters until it gets to a non-digit. Figure 3.10.2 shows the state of the stream after nextInt is invoked.

    A stream of characters after nextInt is invoked.
    Figure \(\PageIndex{2}\): A stream of characters after nextInt is invoked.

    At this point, nextInt returns 45. The program then displays the prompt "What is your name? " and calls nextLine, which reads characters until it gets to a newline. But since the next character is already a newline, nextLine returns the empty string "".

    To solve this problem, you need an extra nextLine after nextInt.

    System.out.print("What is your age? ");
    age = in.nextInt();
    in.nextLine();  // read the newline
    System.out.print("What is your name? ");
    name = in.nextLine();
    System.out.printf("Hello %s, age %d\n", name, age);
    

    This technique is common when reading int or double values that appear on their own line. First you read the number, and then you read the rest of the line, which is just a newline character.


    This page titled 11.10: The Scanner Bug is shared under a CC BY-NC-SA 3.0 license and was authored, remixed, and/or curated by Allen B. Downey (Green Tea Press) .

    • Was this article helpful?