Java - Scanner execute only the Int and “skip” the

2019-06-10 11:26发布

问题:

This question already has an answer here:

  • Scanner is skipping nextLine() after using next() or nextFoo()? 15 answers

While I'm working with java.util.Scanner, I tried to use integers and Strings at data input.

The problem that I faced is, when I input an Int data before a String one, the console skip the String data and go immediately to the next Int one.

Here is my simple problem where the problem is happening :

package justForTest;

import java.util.Scanner;

public class EmptySpaceWorkshop {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        System.out.print("- Enter your Name : ");
        String name = input.nextLine();

        System.out.print("- Enter your IC number : ");
        int icNumber = input.nextInt();

        System.out.print("- Enter your Place of birth : ");
        String placeOfBirth = input.nextLine();

        System.out.print("- Enter your Age : ");
        int age = input.nextInt();

        System.out.println("There once was a wonderful person named " + name+ ", His IC number is " + icNumber );

        System.out.println(". He/She is " + age + " years old. She/He was born at " + placeOfBirth );

    }

}

And here is my output:

- Enter your Name : Ali HISOKA
- Enter your IC number : 123456
- Enter your Place of birth : - Enter your Age : 

I tried a lot to fix this problem. The only solution I could came up with is using input.next(); instead of input.nextLine(); . However, this solution is USELESS for me because as you guys know, when using input.next(); we can only type One Single Word, unlike input.nextLine(); we can type a lot of words which is the thing that I'm looking for. Also I DO NOT want to re-sort (re-arrange) my input and type the Strings data first, then following by the Int data to solve my problem. I want my data to be at the same sort as you seen above in my simple program ( Enter Name, Enter IC Number, Enter Place of Birth, then Enter age). So can I solve this problem ?

I searched a lot on the internet for someone got a problem as mine, but I couldn't find a question and solution for a problem looks exactly like mine.

I already know the reason and the explanation of my problem which is explained by

Joshua

"The reason for the error is that the nextInt only pulls the integer, not the newline. If you add a in.nextLine() before your for loop, it will eat the empty new line and allow you to enter 3 names."

but still it's not helpful for solving my problem.

回答1:

From what I can see it appears that the readLine() is just consuming the newline left after the int was taken from the buffer. A better way to fix this is to use nextLine() to get a string value and convert it:

int icNumber = Integer.parseInt(input.nextLine());


回答2:

Think of your input as a single string:

"Ali HISOKA\n123456\nPLACE\n99"

  • next() consumes the first word, up to first white space - e.g. " " or "\n"
  • nextLine() consumes the first word, up to first new line character
  • nextInt() consumes first word, as next(), and parses it to int - it will throw an exception if the word cannot be parsed.

Now, let's have a look what your calls are consuming:

  1. nextLine() will return "Ali HISOKA", the remaining string is "123456\nPLACE\n99"
  2. nextInt() will return int 123456, the remaining string is "\nPLACE\n99"
  3. nextLine() will return empty string "", the remaining string is "PLACE\n99"
  4. nextInt() will throw an exception, because it will try to parse "PLACE" to int.

The trick is in step 2 - although nextInt() consumes all white spaces between words, it however does not consume new line character, hence nextLine() in step 3 reads empty string because "\n" is first character in the remaining string.

There are two solutions:

  1. Instead of using nextInt() you can read and parse the whole line Integer.parseInt(input.nextLine()). If the line contains a few words, e.g. "1234 abc" it will throw the exception.
  2. Call input.nextLine() after calling nextInt(), so it consumes the remaining string up to first new line character. For input "1234 abc" it will ignore everything after the number.

I would recommend the first solution, because when you are asked for the number and you answer "123 abc", it is not a valid answer. In such case the user should be told that the input is invalid, instead of taking only a valid part from that answer - user would have no clue that part of his answer was ignored.



回答3:

This is a bit confusing because the code you posted does not show your original problem, but the situation after putting in a workaround.

You need to skip the newline after nextInt()

    System.out.print("- Enter your IC number : ");
    int icNumber = input.nextInt();
    input.skip("\\n");

Without the skip, input.newLine (for the place of birth) will match the newline after the entered IC number and you will be prompted for the age.



回答4:

I tried your code at my machine without making any changes and Its working fine.Below is my output.

  • Enter your Name : yash
  • Enter your IC number : 12
  • Enter your Place of birth : alg
  • Enter your Age : 25 There once was a wonderful person named yash, His IC number is 12 . He/She is 25 years old. She/He was born at alg