This question already has answers here:
Why multiple nextInt() works?
(2 answers)
Closed 2 months ago.
Scanner scanner = new Scanner(System.in);
System.out.println("Enter first number");
int FirstNumber = scanner.nextInt();
System.out.println("Entered First Number is" + FirstNumber);
System.out.println("Enter Second Number");
int SecondNumber = scanner.nextInt();
System.out.println("Entered Second Number is" + SecondNumber);
There is no error in the mentioned code everything is perfect but I have a doubt about why we didn't write a scanner.next line() method to handle enter key being pressed after the first number is entered on the console.
nextInt reads the next token in the scanner.
According to the documentation
A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace.
And further down
The default whitespace delimiter used by a scanner is as recognized by Character.isWhitespace().
The documentation for Character.isWhitespace() says that it returns true if the given codepoint
[...]
[...] is '\n', U+000A LINE FEED.
[...]
Which means that \n is a separator, thus it's not part of any token, so you don't need to skip it with a dummy call to nextLine()
Scanner.nextInt() does not read new lines, it only progresses in the current line. See: https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#nextInt()
Related
This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 1 year ago.
In this program, string variable fd doesn't wait taking input.
Can someone help me with this program.
i can get the input if i use the new scanner object though.
import java.util.Scanner;
public class Strmethod {
public static void main(String[] args)
{
String ch,fd;
int s,e;
Scanner sc=new Scanner(System.in);
System.out.print("Enter A String:");
ch=sc.nextLine();
System.out.println("String is "+ch);
System.out.println("Enter Two Numbers For Substring:");
s=sc.nextInt();
e=sc.nextInt();
System.out.println("Substring:"+ch.substring(s,e));
System.out.println("Enter a Word to search:");
fd=sc.nextLine();
System.out.println(ch.contains(f));
String jn=String.join("/","hello","g","u","y","s");
System.out.println(jn);
System.out.println(ch.startsWith("H"));
System.out.println(ch.startsWith("e"));
System.out.println("Length:"+ch.length());
String newstr=ch.replace("Hello","Hey");
System.out.println("String is "+ch);
}
}
The above picture shows the input in the form of a buffer your program is using.
Explanation:
When you first use the nextLine() function it reads the whole buffer up to \n character. Now the next buffer line starts and you have used nextInt() to read an integer 3 again nextInt() to read 6 now you have pressed enter i.e. \n character that is appended to the last of the buffer.
The current position of the buffer is that already contains the \n character so when you use the nextLine() method it consumes the \n character from the buffer and takes no input from the console.
Solution:
The solution is to use the nextLine() whenever using the last nextInt() or similar functions that don't read the full line.
The final program would be
...
System.out.println("Enter Two Numbers For Substring:");
s=sc.nextInt();
e=sc.nextInt();
sc.nextLine(); // <--- to read the last \n character from the buffer
System.out.println("Substring:" + ch.substring(s,e));
System.out.println("Enter a Word to search:");
fd=sc.nextLine();
...
This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 7 years ago.
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.
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:
nextLine() will return "Ali HISOKA", the remaining string is "123456\nPLACE\n99"
nextInt() will return int 123456, 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, hence nextLine() in step 3 reads empty string because "\n" is first character in the remaining string.
There are two solutions:
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.
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.
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());
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.
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
This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 26 days ago.
I am having this problem a lot. When I use a Scanner a lot of times, it doesn't get input from user.
Scanner scan = new Scanner(System.in);
System.out.println("1---");
int try1 = scan.nextInt();
System.out.println("2---");
int try2 = scan.nextInt();
System.out.println("3---");
String try3 = scan.nextLine();
System.out.println("4---");
String try4 = scan.nextLine();
When I run this code, result it :
1---
12
2---
321
3---
4---
aa
As you can see, it skipped at 3rd input. Why this is happening? I solve this problem by using new Scanners, sometimes I have 5-6 different Scanners and it looks so complicated.
Another problem is : there is an error "Resource leak: scan is never closed". I am really confused.
The problem is that by using scanner.nextInt() you only read an integer value, but not the whole line and you don't consume the newline character (\n) that is appended to the line when you press Enter.
Then, when you process reading with scanner.nextLine() you consume the newline character (\n) and from the previous row and don't read the line you want to read. In order to force it to read it, you have to add an additional input.nextLine() statement.
System.out.println("2---");
int try2 = scan.nextInt();
System.out.println("3---");
scan.nextLine(); //<-- fake statement, to move the cursor on the next line
String try3 = scan.nextLine();
Not related to the question, you have to close the Scanner, after finishing work, otherwise the compiler complains with a warning:
scan.close();
Use next API rather than nextLine as when you do nextInt you press enter and it generates number + \n and nextInt is only going to take an integer and won't take \n which in turn gets passed to next input i.e. try3 which is why it gets skipped.
Scanner scan = new Scanner(System.in);
System.out.println("1---");
int try1 = scan.nextInt();
System.out.println("2---");
int try2 = scan.nextInt();
System.out.println("3---");
String try3 = scan.next();
System.out.println("4---");
String try4 = scan.next();
Well, for the first question use
scan.next()
insted of using
scan.nextLine();
For the second question I'd recommend using try, assuming you need to close your scan as your compiler is warning: "Resource leak: scan is never closed"
Scanner scanner= null;
try {
scanner= new Scanner(System.in);
}
finally {
if(scanner!=null)
scanner.close();
}
I have the following Java code:
Scanner input = new Scanner(System.in);
try {
System.out.println("Enter your name>>");
String name = input.next();
System.out.println("Enter your year of birth>>");
int age = input.nextInt();
System.out.println("Name: " + name);
System.out.println("Year of Birth: " + age);
System.out.println("Age: " + (2012 - age));
} catch (InputMismatchException err) {
System.out.println("Not a number");
}
When I enter a name with a space (e.g. "James Peterson"), I get the next line output correctly (Enter your year of birth) and then an InputMismatchException immediately. The code works with a single name without spaces. Is there something I'm missing?
System.out.println("Enter your name>>");
String name = input.next();
System.out.println("Enter your year of birth>>");
int age = input.nextInt();
Scanner, breaks its input into tokens using a delimiter pattern, which by default matches whitespace.
When you enter "James Peterson", Scanner#next() takes "James" as a token and assigns it to String name and then you do a Scanner#nextInt() which takes "Peterson" as the next token, but it is not something which can be cast to int and hence the InputMismatchException asnextInt() will throw an InputMismatchException if the next token does not match the Integer regular expression, or is out of range.
Actually the problem in your code has been clearly pointed out. In your case, there are two typical ways to achieve that:
One
Using useDelimiter method to delimite the input and after each input, you need to hit the Enter.
Sets this scanner's delimiting pattern to a pattern constructed from the specified String.
In your case, you need to
Scanner sc = new Scanner(System.in);
sc.setDelimiter("\\n");
// hit the "Enter" after each input for the field;
Two
Also you can achieve the same result using readLine
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.
In this way, you can do
Scanner sc = new Scanner(System.in);
System.out.println("Enter your name>>");
String name = sc.nextLine();
...
System.out.println("Enter your year of birth>>");
int age = sc.nextInt();
P.S.
Actually you can achieve it in a more restrictive way, controlling the pattern using next(Pattern pattern), if you need it.
int age = sc.next(Pattern.compile("\\d+{1,3}"));
In this case, if the input DOES NOT match the pattern, it will throw InputMismatchException as you were trying to nextInt while the input is a string.
When I enter a name with a space (e.g. "James Peterson"), I get the next line output correctly (Enter your year of birth>>) and then an InputMismatchException immediately.
Would anyone point me in the right direction, of why when i use a for loop the println function comes up two times in the output. Thanks
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter the number of employees to calculate:");
int numberEmployees = scan.nextInt();
for(int i=0; i<numberEmployees; i++){
System.out.println("Enter First Name:");
name = scan.nextLine();
System.out.println("Enter Last Name:");
last = scan.nextLine();
System.out.println("Enter Document #:");
document = scan.nextInt();
System.out.println("Enter Basic Salary");
basicSalary = scan.nextInt();
System.out.println("Enter # of Hours");
hours = scan.nextInt();
}
}
OUTPUT
Enter the number of employees to calculate:
1
Enter First Name:
Enter Last Name:
daniel
Enter Document #:
The problem is that when you entered 1 with a new line, the nextInt() function doesn't remove the newline that you had from entering in the 1. Change your calls to scan.nextInt() to Integer.parseInt(scan.nextLine()) and it should behave the way you want.
To further explain; here's stuff from the Java API.
A Scanner breaks its input into tokens using a delimiter pattern,
which by default matches whitespace. The resulting tokens may then be
converted into values of different types using the various next
methods.
and
The next() and hasNext() methods and their primitive-type companion
methods (such as nextInt() and hasNextInt()) first skip any input that
matches the delimiter pattern, and then attempt to return the next
token. Both hasNext and next methods may block waiting for further
input.
So, what evidently happens (I didn't see anything on the page to confirm it) is that after next(), hasNext(), and their related methods read in a token, they immediately return it without gobbling up delimiters (in our case, whitespace) after it. Thus, after it read in your 1, the newline was still there, and so the following call to nextLine() had a newline to gobble and did so.
It appears that the newline character remains in your input after the first entry. When the next input is requested, the Scanner sees a newline character and interprets it as the end of the input. This makes it appear to skip every other input request. I would suggest checking out the Java API docs as to the exact behavior of Scanner's methods.