This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 9 years ago.
When I execute my code my program is terminated without scanning the string.
double x, y;
String s;
Scanner scan = new Scanner(System.in);
System.out.println("Enter Number: ");
x = scan.nextDouble();
System.out.println("Enter Number 2: ");
y = scan.nextDouble();
System.out.println("Enter Operater: x,+,/,-");
s = scan.nextLine();
if(s.equals("x"))
{
System.out.print(x * y);
}
else if(s.equals("+"))
{
System.out.print(x + y);
}
else if(s.equals("/"))
{
System.out.print(x / y);
}
else if(s.equals("-"))
{
System.out.print(x - y);
}
scan.close();
my program ends before s = scan.nextline();
How come it ends before?
End of line you leave in the buffer.
next( ) reads a token from the buffer until the next white space, while nextLine( ) reads up to \n
...
System.out.print("Enter Number 2: ");
y = scan.nextDouble();
System.out.print("Enter Operater: x,+,/,-");
s = scan.next();
...
Enter Number: 1
Enter Number 2: 2
Enter Operater: x,+,/,--
-1.0
The user input, optimally, would look like this:
-CURSOR HERE- num1 NEWLINE
num2 NEWLINE
operator NEWLINE
If you do several nextDouble() calls, the program will read one double first.
num1 -CURSOR HERE- NEWLINE
num2 NEWLINE
operator NEWLINE
Then, the user must type an enter to submit the input, so the second nextDouble() can't find anything to read, since there is no number directly after the cursor. It needs a nextLine() to absorb the newline.
Unfortunately, you have a nextLine() in the wrong place, which absorbs the newline.
num1 NEWLINE
-CURSOR HERE- num2 NEWLINE
operator NEWLINE
So, your program absorbs the double in the first nextDouble(), nothing in the second, and the newline in nextLine().
To fix this, put a scan.nextLine() right after each nextDouble(). You don't have to read the nextLine() calls into anything, other than the one that has the operator.
Related
I am wondering how I can stop the scanner from reading extra erroneous input from the user.
For example, I would like to read in the user input 2 one as 2 into the variable diam, which the program below achieves.
The issue is then, that the next loop automatically detects the one leftover from the input, and executes the if statement accordingly.
I was able to work around this by creating two scanners, but unfortunately this is not allowed for this particular assignment. In addition, we are required to use .hasNextInt() in our program.
How do I prevent this "spill-over" using only one scanner? I have to assume this question has been posed before, but I did not have much luck finding an answer.
Scanner scnr = new Scanner(System.in);
System.out.print("Enter the diameter of a "
+ "cylinder (in centimeters): ");
// BEGIN: diameter input verification loop
for (;;) {
if (!scnr.hasNextInt()) {
System.out.print("Please enter an integer value "
+ "(less than 2,147,483,648) as decimal digits: ");
scnr.nextLine();
continue;
}
diam = scnr.nextInt();
if (diam >= 0) {
//null statement
}
else {
System.out.print("Please enter a positive integer value: ");
continue;
}
break;
}
//END: diameter input verification loop
//prompts user for container height
System.out.print("Enter the height of a "
+ "cylinder (in centimeters): ");
// BEGIN: height input verification loop
for (;;) {
if (!scnr.hasNextInt()) {
System.out.print("Please enter an integer value "
+ "(less than 2,147,483,648) as decimal digits: ");
scnr.nextLine();
continue;
}
height = scnr.nextInt();
if (height >= 0) {
//null statement
}
else {
System.out.print("Please enter a positive integer value: ");
continue;
}
break;
}
//END: height input verification loop`
One option would be to just read the entire line of input from the Scanner, and then retain only the first word. For example, for the diameter of a cylinder you could use:
System.out.print("Enter the diameter of a cylinder (in centimeters): ");
String input = scnr.nextLine();
try {
int diam = Integer.parseInt(input.split(" ")[0]);
}
catch (NumberFormatException e) {
System.out.print("Please enter an integer value "
+ "(less than 2,147,483,648) as decimal digits: ");
}
I can think of a couple of approaches:
As Tim notes, you can use readLine() to read a complete line from the user, then parse the line. You could use split, or create a new Scanner to parse the line, or various other approaches.
You can stick with a single Scanner and call nextLine() to discard unconsumed characters up to and including the next end-of-line. Obviously, you need to do this after calling nextInt(). For example:
height = -1;
while (height < 0) {
if (!scnr.hasNextInt()) {
System.out.print("Please enter an integer value "
+ "(less than 2,147,483,648) as decimal digits: ");
} else {
height = scnr.nextInt();
if (height < 0) {
System.out.print("Please enter a positive integer value: ");
}
}
scanner.nextLine();
}
(The above version of your code has restructured things to get rid of the break and continue. The restructuring also allows me to put the readLine as an unconditional last statement for the loop. I think it makes the logic easier to understand ...)
// BEGIN: height input verification loop
for (;;) {
scnr.nextLine(); /* read fresh input, deleting the left over input */
if (!scnr.hasNextInt()) {
System.out.print("Please enter an integer value " + "(less than 2,147,483,648) as decimal digits: ");
scnr.nextLine();
continue;
}
height = scnr.nextInt();
if (height >= 0) {
// null statement
} else {
System.out.print("Please enter a positive integer value: ");
continue;
}
break;
}
You can simply add a scnr.nextLine() to remove the "old" scnr left over from the previous input. This fixes the spill-over problem.
In the below code:
secondI = scan.nextInt();
System.out.println("double");
secondD = scan.nextDouble();
System.out.println("string");
secondS = scan.nextLine();
After entering the double value, it is skipping the string entry part. How can I fix this?
secondI = scan.nextInt();
System.out.println("double");
secondD = scan.nextDouble();
scan.nextLine();
System.out.println("string");
secondS = scan.nextLine();
You need to have this extra nextline statement which consumes the remaining section of that line which you entered for the double value.
Use
secondS = scan.next();
instead of
secondS = scan.nextLine();
Please see the documentation for Scanner.nextLine().
Advances this scanner past the current line and returns the input that was skipped.
Try using other methods of the Scanner class such as Scanner.next()
This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 7 years ago.
I don't know why, but the below code makes the user run the code again, whether they choose to or not. I've tried many things, but it doesn't work correctly.
Thanks!
public static void main (String [ ] args)
{
boolean a = true;
while (a)
{
Scanner scan = new Scanner(System.in);
System.out.print("Enter an integer: ");
int x = scan.nextInt();
System.out.print("\n\nEnter a second integer: ");
int z = scan.nextInt();
System.out.println();
System.out.println();
binaryConvert1(x, z);
System.out.println("\n\nWould you like to run this code again? Enter \"Y\" or \"N\".");
System.out.print("Enter your response here: ");
String RUN = scan.nextLine();
String run = RUN.toLowerCase();
if (run.equals("n"))
{
a = false;
}
System.out.println();
System.out.println();
}
System.out.println("Goodbye.");
}
Scanner.nextInt() doesn't consume the line ending characters from the buffer, which is why when you read the value of the "yes/no" question with scan.nextLine(), you'll receive an empty string instead of the value the user entered.
A simple way to fix this is to explicitly parse the integer from raw lines using Integer.parseInt():
System.out.print("Enter an integer: ");
int x = Integer.parseInt(scan.nextLine());
System.out.print("\n\nEnter a second integer: ");
int z = Integer.parseInt(scan.nextLine());
This question already has an answer here:
How to use java.util.Scanner to correctly read user input from System.in and act on it?
(1 answer)
Closed 7 years ago.
I'm trying to teach my friend Java. I tried this simple calculator.
public static void main(String[] args) {
boolean powerOn = true;
while(powerOn) {
#SuppressWarnings("resource")
Scanner userInput = new Scanner(System.in);
System.out.println("Welcome to the calculator\nPlease enter a number (Enter 3.14 for PI)");
double firstNumber = userInput.nextDouble();
if(firstNumber == 3.14) firstNumber = Math.PI;
System.out.println("Please enter an operation(+,-,*,/, Square Root)");
String operation = userInput.next();
if(operation.equalsIgnoreCase("Square Root")) System.out.println(Math.sqrt(firstNumber));
else {
System.out.println("Please enter another number");
double secondNumber = userInput.nextDouble();
if(secondNumber == 3.14) secondNumber = Math.PI;
if (operation.equals("+")) {
if(firstNumber == 9 && secondNumber == 10) System.out.println("21");
else System.out.println(firstNumber+secondNumber);
}
else if (operation.equals("-")) System.out.println(firstNumber-secondNumber);
else if (operation.equals("*")) System.out.println(firstNumber*secondNumber);
else if (operation.equals("/")) System.out.println(firstNumber/secondNumber);
}
System.out.println("Power off?");
String off = userInput.next();
if(off.contains("y")) System.exit(1);
}
}
If you do square root, it prints enter another number and then throws an exception... I know what's happening, but why and how do I prevent it?
And just a side note can someone explain to me the difference between Scanner#next() and Scanner#nextLine?
next() returns the string before the space while nextLine() as you might have guessed returns the whole line .
You are probably also getting the error because of the same reason as your string "Square Root" has a space and hence operation variable always have "Sqaure" value assigned to it rather than "Square Root".
This pushes it to the else block instead of if.
To fix your issue add a scan.nextLine();
Before you scan in the operation. And while scanning in the operation use a scan.nextLine(); as well instead of the scan.next();
Think of the scan as the location of the cursor. A scan.nextDouble(); will place the cursor after the last digit of the number, and a scan.nextLine(); will scan in what ever is inbetween the cursor's location and the beginning of the next line. scan.next(); won't scan in the entire line.
You need to update the following code
String operation = userInput.next();
with following
String operation = userInput.nextLine();
The reason being the next() will only return what comes before a space. nextLine() automatically moves the scanner down after returning the current line.
In your current code, when you try to get the square root, the operation will just store "Square" instead of "Square Root" and therefore the following if condition isn't satisfied
if(operation.equalsIgnoreCase("Square Root"))
and the code goes into else condition and asks for another number and tries to process it and in the else block it throws error on this line
double secondNumber = userInput.nextDouble();
Apart from changing the next() to nextLine() in your code, you need to update following
double firstNumber = userInput.nextDouble();
with
double firstNumber = userInput.nextDouble();
userInput.nextLine();
to ensure that the scanner doesn't skip your nextLine() because in nextDouble() method only the double is consumed and the next line characters (\n) aren't.
Similarly update
double secondNumber = userInput.nextDouble();
with
double secondNumber = userInput.nextDouble();
userInput.nextLine();
For more info about skipping of nextLine() method while using nextDouble() refer this link.
This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 8 years ago.
I'm trying to make a GPA calculator but early on in the code I started having issues; here's the code segment:
Scanner input = new Scanner(System.in);
System.out.println("How many grades are you putting? ");
int length = input.nextInt();
String[] gradesArray = new String[length];
for(int i = 0; i < gradesArray.length; i++)
{
System.out.println("Enter grade (include + or -) ");
gradesArray[i] = input.nextLine();
}
it all goes well until the "Enter grade (include + or -) " part, it repeats twice, so when I compile and get to that part it says "Enter grade (include + or -) Enter grade (include + or -) " before I can type in anything. How can I fix this repeating issue? Because I think it also takes the spot of one grade.
You can fix this by adding
input.nextLine();
after
int length = input.nextInt();
This will make sure that the end of the line that contained that integer is consumed before you try to read more input.
Scanner input = new Scanner(System.in);
System.out.println("How many grades are you putting? ");
int length = input.nextInt();
input.nextLine();
String[] gradesArray = new String[length];
for(int i = 0; i < gradesArray.length; i++)
{
System.out.println("Enter grade (include + or -) ");
gradesArray[i] = input.nextLine();
}
Further explanation:
Calling input.nextInt() attempts to read a single token from the standard input and convert it to an int. After you type that integer and hit enter, the input stream still contains the end of line character[s], which haven't been read by input.nextInt(). Therefore, the first time you call input.nextLine(), it reads those characters and then discards them (since input.nextLine() strips newline characters), and you end up getting an empty String. That empty String is assigned to gradesArray[0], and the loop proceeds immediately to the next iteration. Adding an input.nextLine() before the loop solves the problem.