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.
Related
First post/question here and very new to java. Trying to make a small text based movie database app. One part of it is to add a review. The problem is when I just hit [enter] when asked for a Score number [0-10] on the review, the prompt just drops one step down and keeps waiting for input. I want it to be impossible to leave this field blank. Here is what I have so far:
int score;
do {
while (!sc.hasNextInt()) {
sc.next();
System.out.print("\nInvalid input! ");
System.out.print("Please enter a number from 0-10: ");
}
score = sc.nextInt();
if (!(score >= 0 && score <= 10)) {
System.out.print("\nInvalid input! ");
System.out.print("Please enter a number from 0-10: ");
}
} while (!(score >= 0 && score <= 10 ));
Scanner is reading tokens, i.e. text separated by whitespaces. That means, that as long as you just press Enter, the next token hasn't even started yet.
One of the fallacies of Scanner is that it's so easy to use, but even easier to misuse, e.g. mishandling user input.
Example: What should happen if used enters 123 abc<enter>? Your code will read 123 and continue, leaving abc in the buffer for the next prompt, which might want text and hence read the abc as that text. Oops!!
Most of the time, to handle bad user input, you should never use hasNextXxx() and nextXxx() methods other than nextLine(). It's the only way to ensure you get one answer (input) for one prompt.
So, you should do something like this:
int score;
for (;;) {
System.out.print("Please enter a number from 0-10: ");
String line = sc.nextLine();
try {
score = Integer.parseInt(line.trim());
} catch (NumberFormatException e) {
System.out.println("Invalid input! Not a number.");
continue;
}
if (score < 0 || score > 10) {
System.out.println("Invalid input! Out of range.");
continue;
}
break;
}
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;
}
}
}
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);
In the below code, I ask the user to give an integer input and if the input is 0 or a negative number, it loops again until the positive number is given. The thing is that if the users presses a letter, my code crashes and despite the fact that I used try-catch in a lot of ways nothing really worked. Any ideas?
I used try-catch inside the loop, but it only worked for one letter input and not correctly.
System.out.print("Enter the number of people: ");
numberOfPeople = input.nextInt();
while (numberOfPeople <= 0) {
System.out.print("Wrong input! Enter the number of people again: ");
numberOfPeople = input.nextInt();
}
The problem in your current code is that you're always trying to read an int so when receiving a non-integer input you can't handle the error in the right way. Modify this to always read a String and convert it into an int:
int numberOfPeople = 0;
while (numberOfPeople <= 0) {
try {
System.out.print("Enter the number of people: ");
numberOfPeople = Integer.parseInt(input.nextLine());
} catch (Exception e) {
System.out.print("Wrong input!");
numberOfPeople = 0;
}
}
//continue with your life...
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)
//...