My scanner asks for an input twice - java

I seem to have this problem a lot, I can't quite seem to understand how to work scanners
System.out.println("Please enter a number");
Scanner choice1 = new Scanner(System.in);
int choiceH = choice1.nextInt();
while(!choice1.hasNextInt()){
System.out.println("Please enter a number");
choice1.next();
}
What I want the code to do is ask for a number, and check if the input is a number.
My problem is that it asks fro the number twice and I don't know why.

In the line
Scanner choice1 = new Scanner(System.in);
the buffer will be empty. When you reach the line
int choiceH = choice1.nextInt();
you enter a number, and you press Enter. After this, the number will be stored in the buffer and be consumed (the buffer will be empty again). When you reach the line
while (!choice1.hasNextInt())
the program will check if there is an int in the buffer, but at this moment, it will be empty, so hasNextInt will return false. So, the condition will be true and the program will ask for an int again.
How can you solve it? You can delete the first nextInt:
System.out.println("Please enter a number");
Scanner choice1 = new Scanner(System.in);
int choiceH = -1; // some default value
while (!choice1.hasNextInt()) {
System.out.println("Please enter a number");
choice1.nextInt();
}

If this line of code successfully executes:
int choiceH = choice1.nextInt();
Then the user has entered an int and the parsing succeeded. There's no reason to check hasNextInt() again.
If the user didn't enter an int, then nextInt() will throw an InputMismatchException, and you should simply catch it, and prompt the user again.
boolean succeeded = false;
int choiceH = 0;
Scanner choice1 = new Scanner(System.in);
do {
try {
System.out.println("Please enter a number");
choiceH = choice1.nextInt();
succeeded = true;
}
catch(InputMismatchException e){
choice1.next(); // User didn't enter a number; read and discard whatever was entered.
}
} while(!succeeded);

Related

How to validate that input to Scanner is an int?

System.out.println("Enter your age here:");
setAge(sc.nextInt());
How can I validate that users' age is not a char or a negative number?
Ideally, if the users input anything but an int, the program would ask for the input again.
I have tried using a do-while, but doesn't seem to be working.
I am a beginner. Any help is super appreciated.
Thanks!
What you are doing with sc.nextInt() will only allow the user to enter an int or the program will throw an InputMismatchException (thus that part behaves the way you want). If you want to make sure the number isn't negative though, do this:
System.out.println("Enter your age here:");
while (!sc.hasNextInt()) {
System.out.println("Please enter an integer.");
sc.next();
}
int age = sc.nextInt();
if(age < 0) {
//do what you want if the number is negative
//if you're in a loop at this part of the program,
//you can use the continue keyword to jump back to the beginning of the loop and
//have the user input their age again.
//Just prompt them with a message like "invalid number entered try again" or something to that affect
}
else {
setAge(age);
//continue execution
}
The following block will do what you need:
int age;
System.out.println("Please enter an integer");
while (true) {
try{
age= scan.nextInt();
if (age<=0) throw new Exception("Negative number");
break;
} catch(Exception e){
System.out.println("Please enter a positive integer");
}
scan.nextLine();
}
// below just call
setAge(age);
I hope this helps.

Validate User Input, check if input is positive number and not string of characters

I'm trying to write a program that can validate user's input before going to the next section, but i'm currently stuck with this. Whenever i enter a negative value first, it will bypass the condition or crashes.
If i input "A" , it will show "Please enter a valid number"
If i input "-1", it will show "Please enter a positive number"
But soon after i enter -1, if I input another negative value, it by pass the condition and accept the negative value, while input character will crashed the program.
What i want to achieve here to have a program that can
Check whether Input is number and not letter or string, and check if it's positive number
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int Users = 0;
boolean isNumber;
System.out.print("Enter the number of Users ");
do {
if (input.hasNextInt()) {
Users = input.nextInt();
isNumber = true;
if (Users < 0) {
System.out.print("Please enter a positive number ");
Users = input.nextInt();
}
} else {
System.out.print("Please enter a valid number ");
isNumber = false;
input.next();
}
} while (!(isNumber));
}
You're not setting isNumber to False if it's less than 0. This means that, if you ever enter a negative value (and you haven't entered a string before), your program will ask you for another number again and it won't check if it's negative as isNumber will be True, meaning that the while loop will no longer run.
To fix this, add isNumber = False; to the end of the if (Users<0){ code block.
I see three problems with your code. The first one is that isNumber is being set to true even if the input is a negative number, so I would recommend only setting it to true after you've verified that it's not negative.
The second problem is that in your if (Users < ) { ... } block, you're getting input.nextInt(). You should really just go to the next iteration of the do-while loop and get the next input on the next iteration.
Third, you should initialize isNumber to false;
Try this code:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int Users = 0;
boolean isNumber = false;
System.out.print("Enter the number of Users ");
do {
if (input.hasNextInt()) {
Users = input.nextInt();
if (Users < 0) {
System.out.print("Please enter a positive number ");
// Remove this line:
// Users = input.nextInt();
} else {
// Moved this to an else block:
isNumber = true;
}
} else {
System.out.print("Please enter a valid number ");
// remove this because it's already initialized to false:
// isNumber = false;
input.next();
}
} while (!(isNumber));
}

How do I let the user input the variable again after doing an error?

import java.util.Scanner;
public class LeapYear {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
System.out.println("Please enter a year on the Gregorian calendar. (After 1583)");
int yearEntered = scan.nextInt();
if (yearEntered < 1583){
System.out.println("Please enter an integer greater than 1582");
System.out.println("Try again");
}else{
int yearEntered = scan.nextInt();
//this is where I'm messing up
Before I show you can make the user enter the variable again, I want to point out that you are declaring yearEntered again in the else, which is illegal in Java. Simply removing the int there will fix that.
Now, if you had an error from the user entering the wrong input (i.e. 2015 instead of 1580), you can do this:
Scanner scan = new Scanner(System.in);
System.out.println("Please enter a year on the Gregorian calendar. (After 1583)");
int yearEntered = 0; //initialize the variable with a default number
while (scan.hasNext()) { //keep scanning for the user input
yearEntered = scan.nextInt(); //scan for the next int assuming the user only enters ints
if (yearEntered < 1583) { //if the user entered less than 1583, then do another iteration till the user finally enters a number greater than or equal to 1582
System.out.println("Please enter an integer greater than 1582");
System.out.println("Try again");
} else {
break; //exits the loop
}
}
//code for what you want to do with the correct yearEntered

Scanner loop doesn't cycle when hitting enter twice

boolean loop = false;
double numberOfStudents;
System.out.print("Enter a number: ");
if ((scnr.nextLine().trim().isEmpty()) ) {
loop = true;
}
while (loop) {
System.out.println("Enter a number");
if (scnr.hasNextDouble() ){
System.out.println("Loop has stopped");
numberOfStudents = scnr.nextDouble();
loop = false;
}
}
System.out.println("You're outside the loop!");
I'm trying to get the program to say "Enter a number" until the user has entered an actual number (no white spaces or letters or signs). When the user has entered a number, it sets numberOfStudents equal to that number and breaks out of the loop.
But if you hit enter twice, it doesn't iterate. It only displays "Enter a number" once.
What is wrong with the loop logic? Why isn't it looping until valid input is taken?
For the actual answer to your question of "Why doesn't 'Enter a number' display more than once?" see Tom's comment (update: Tom's answer).
I've rewritten your loop in a way which preserves your code, but also makes it a little easier to handle format exceptions (though at the risk of silently swallowing an exception -- should be acceptable for this use case).
Can be up to you to use this design, here is an SO post on why empty catch blocks can be a bad practice.
public static void main(String args[])
{
boolean loop = true;
double numberOfStudents;
Scanner scnr = new Scanner(System.in);
while(loop){
System.out.print("Enter a number: ");
String input = scnr.nextLine();
try{
numberOfStudents = Double.parseDouble(input);
loop = false;
}catch(NumberFormatException e){
}
}
System.out.println("You're outside the loop!");
}
Output:
Enter a number:
Enter a number:
Enter a number:
Enter a number: 50
You're outside the loop!
First of all: Since you're reading from System.in a call to the input stream will block until the user entered a valid token.
So let's check first scan using your scnr variable:
scnr.nextLine()
nextLine() reads everything til the next line delimiter. So if you just press return, then it will successfully read it and will perform the next stuff.
The next call is:
scnr.hasNextDouble()
This call expects a "real" token and ignores white spaces, except as a delimiter between tokens. So if you just press return again it doesn't actually read that input. So it still waits for more (for the first token). That is why it stucks in your loop and you won't get another "Enter a number" output.
You can fix that by either enter a real token, like a number, or by changing the loop like trobbins said.
I hope you now understand your program flow a bit more :).
While trobbins code basically solves your problem, it's bad practice to use exceptions for flow control.
I used a small regexp to check if the value is a number. But this example is not complete, it will still crash it the user enters for example two decimal points. So you would need to create a proper number check or just use integers where the check is much easier.
Someone in the comments pointed out that people may want to enter scientific notation like 5e10, so this would also be another case to check for. If this is just some code you need as a proof of concept or something quick and dirty, you can go with the exception handling method but in production code you should avoid using exceptions this way.
double numberOfStudents;
Scanner scnr = new Scanner(System.in);
while(true) {
System.out.print("Enter a number: ");
String input = scnr.nextLine().trim();
if(input.matches("^[0-9\\.]{1,}$")) {
System.out.println("Loop has stopped");
numberOfStudents = Double.parseDouble(input);
break;
}
}
System.out.println("You're outside the loop!");
The following code should help you:
double numberOfStudents = 0;
Scanner scnr = new Scanner(System.in);
boolean readValue = false; //Check if the valid input is received
boolean shouldAskForNumber = true; //Need to ask for number again? Case for Enter
do {
if (shouldAskForNumber) {
System.out.print("Enter a number:");
shouldAskForNumber = false;
}
if (scnr.hasNextDouble()) {
numberOfStudents = scnr.nextDouble();
readValue = true;
} else {
String token = scnr.next();
if (!"".equals(token.trim())) { //Check for Enter or space
shouldAskForNumber = true;
}
}
} while (!readValue);
System.out.printf("Value read is %.0f\n", numberOfStudents);
System.out.println("You're outside the loop!");
Update
Understood the following statement in question different way:
But if you hit enter twice, it doesn't loop back. It only displays
"Enter a number" once.
The code is set to print "Enter a number" only once if the user hits RETURN/ENTER or enters space character. You may remove the special check and use the code if needed.
import java.util.Scanner;
public class Testing {
public static boolean checkInt(String s)
{
try
{
Integer.parseInt(s);
return true;
} catch (NumberFormatException ex)
{
return false;
}
}
public static void main(String[] args) {
boolean loop = false;
double numberOfStudents;
Scanner scnr = new Scanner(System.in);
String input = "";
while (!(checkInt(input))) {
System.out.println("Enter a number");
input = scnr.nextLine();
}
numberOfStudents = Integer.parseInt(input);
System.out.println("Number of students: " + numberOfStudents );
}
}
//this code is working fine, if you want you check it out.
//In your code your taking another input if the first is an int/double; if the first input is not a number then you have mentioned to take input again..
Use a debugger to see what the code is actually doing. Here's a guide on debugging in Eclipse. After you have finished debugging your code, you will probably know what the problem is.
Below code will help you
boolean loop = true;
double numberOfStudents;
Scanner scnr = new Scanner(System.in);
System.out.print("Enter a number: ");
String input = scnr.nextLine();
while(!scnr.hasNextDouble()){
System.out.print("Enter a number: ");
try{
numberOfStudents = Double.parseDouble(input);
break;
}catch(NumberFormatException e){
}
input = scnr.nextLine();
}
System.out.println("You're outside the loop!");
The following code is working,
boolean loop = true;
double numberOfStudents;
Scanner scnr=new Scanner(System.in);
while(loop) {
System.out.println("Enter a number");
if ((scnr.nextLine().trim().isEmpty()) ) {
loop = true;
}
if (scnr.hasNextDouble() ){
System.out.println("Loop has stopped");
numberOfStudents = scnr.nextDouble();
loop = false;
}
}
System.out.println("You're outside the loop!");
The output is,
run:
Enter a number
hj
po
Enter a number
lhf
Enter a number
o
Enter a number
p
Enter a number
a
Enter a number
34
Loop has stopped
You're outside the loop!
You have to scan the next line if you want to get more values form the scanner again. The code should be like:
while (loop) {
System.out.println("Enter a number");
if(!(scnr.nextLine().trim().isEmpty())){
if (scnr.hasNextDouble() ){
System.out.println("Loop has stopped");
numberOfStudents = scnr.nextDouble();
loop = false;
}
}
}

Testing for blank input using Scanner class during input validation

I need to ask the user to enter a positive non-zero integer from the console that I will use as a product number in my program.
If I enter any non-integer value, the program correctly enters the while loop.
If I enter a 0 or a negative integer, the program correctly throws the exception (which I catch and handle elsewhere).
When I just press the enter key (or end of line character) it seems that the program just puts the console to another line. I want it to enter the while loop to display the error message. I think the cause is that hasNextInt() will wait until the token is a non end of line character input.
private static void validateProductNumber() throws InvalidProductNumberException {
Scanner keyboard = new Scanner(System.in);
int number;
while(!keyboard.hasNextInt()) {
System.out.println("Number must be an integer. Try again. ");
System.out.println("Enter a new number: ");
keyboard.next();
}
number = keyboard.nextInt();
if (number <= 0)
throw new InvalidProductNumberException();
newNumber = number;
}
Is there another way I can implement my input validation with Scanner class so that it works correctly for all situations?
You can change your loop as follows:
while(true) {
try {
System.out.println("Enter a new number: ");
//read the line and parse it
number = Integer.parseInt(keyboard.nextLine());
break; //break the loop if the input is a valid integer
} catch(Exception ex) {
//print the error message if the input is incorrect
System.out.println("Number must be an integer. Try again. ");
}
}
if (number <= 0)
//...

Categories

Resources