This question already has an answer here:
While I'm working with java.util.Scanner
, I tried to use integers and String
s 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.
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()
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.I tried your code at my machine without making any changes and Its working fine.Below is my output.
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 usenextLine()
to get a string value and convert it: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 characternextInt()
consumes first word, asnext()
, 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:
nextLine()
will return"Ali HISOKA"
, the remaining string is"123456\nPLACE\n99"
nextInt()
will return int123456
, the remaining string is"\nPLACE\n99"
nextLine()
will return empty string""
, the remaining string is"PLACE\n99"
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, hencenextLine()
in step 3 reads empty string because"\n"
is first character in the remaining string.There are two solutions:
nextInt()
you can read and parse the whole lineInteger.parseInt(input.nextLine())
. If the line contains a few words, e.g."1234 abc"
it will throw the exception.input.nextLine()
after callingnextInt()
, 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.