I have this try/catch wrapped around a do/while loop because after the try/catch throws the error message, I want it to loop back to the top. I tried do/while, while, and I tried placing the while loop at different places in my code but nothing works. The program works fine until an exception is thrown and then it goes into an infinite loop. After is displays the error message, I just want it to loop back up to the top.
public static void main(String[] args) {
Scanner input = new Scanner( System.in );
Integer userInput;
do {
try{
System.out.print("Enter a number? \n");
userInput = input.nextInt();
if ( userInput == 1 )
Animal1.displayMessage ();//Display the total
if( userInput == 2 )
Animal2.displayMessage ();//Display the total
}
catch (Exception e) {
System.out.println(" That's not right ");
break;
}
} while (true);
}
}
This is what it does after displaying an error message.
Enter a number?
That's not right
Enter a number?
That's not right
Enter a number?
That's not right
Enter a number?
That's not right
Enter a number?
That's not right
Enter a number?
That's not right
Enter a number?
That's not right
Enter a number?
That's not right
Enter a number?
Enter a number?
If I don't stop it, it just keeps going.
you can try this workaround:
public static void main(String[] args) {
Scanner input = new Scanner( System.in );
Integer userInput;
do {
try{
System.out.print("Enter a number? \n");
userInput = input.nextInt();
if ( userInput == 1 )
Animal1.displayMessage ();//Display the total
if( userInput == 2 )
Animal2.displayMessage ();//Display the total
}
catch (Exception e) {
System.out.println(" That's not right ");
input.next();
}
} while (true);
}
}
or if you want to avoid try-catch:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Integer userInput = 0;
do {
System.out.print("Enter a number? \n");
if (input.hasNextInt())
userInput = input.nextInt();
else {
System.out.println(" That's not right ");
input.next();
}
if (userInput == 1)
Animal1.displayMessage ();//Display the total
;// Display the total
if (userInput == 2)
Animal2.displayMessage ();//Display the total
} while (true);
}
You can give 3 options - one option to exit
System.out.print("Enter a number? \n 1 to display Animal1 total\n2 to display Animal2 total\n 3 to exit");
Inside while loop, you can add
if ( userInput == 3) break;
You need to put the try/catch statements outside of the loop.
Related
This question already has answers here:
How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
(5 answers)
java.util.NoSuchElementException - Scanner reading user input
(5 answers)
Closed 19 days ago.
I'm new to Java, just started a couple days ago. I have this program wich does some cool checks on an input number, but for semplicity i just created a class TestToFixLoopIssue because loop is actually the issue im facing. When we choose to enter a number, we enter the if with choice == 1, so the Test class is called, does its things, and when we quit that "program" we get an infinite loop in the console. This does not happen if i just copy paste the Test code into the if (removing its Scanner). So i think its a problem related to the multiple Scanners, but i dont know how to fix it.
EDIT: i tryed adding s.next(); but this does not fix the issue, it just gives another error in console wich stops the program:
Exception in thread "main" java.util.NoSuchElementException
public class Program {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
boolean exit = false;
while (!exit) {
System.out.println("What do you want to do?");
System.out.println("1. Check a number");
System.out.println("2. What is this program about?");
System.out.println("3. Quit");
if (s.hasNextInt()) {
int choice = s.nextInt();
s.nextLine();
if (choice == 1) {
System.out.println(" ");
// NumberChecker nc1 = new NumberChecker();
// nc1.check();
TestToFixLoopIssue test1 = new TestToFixLoopIssue();
test1.check();
} else if (choice == 2) {
System.out.println(" ");
System.out.println("This program checks multiple properties of a number.");
} else if (choice == 3) {
exit = true;
System.out.println(" ");
System.out.println("Program closed!");
} else {
System.out.println(" ");
System.out.println("Invalid choice. Try again.");
}
} else {
System.out.println("Invalid input. Try again.");
}
}
s.close();
}
}
public class TestToFixLoopIssue {
public void check() {
Scanner scan = new Scanner(System.in);
boolean repeat = true;
while (repeat) {
System.out.print("Insert a number: ");
int number = scan.nextInt();
System.out.println(" ");
System.out.println("You inserted " + number);
System.out.println("Do you want to check another number?");
System.out.println("1. Yes");
System.out.println("2. No");
if (scan.nextInt() == 2) {
repeat = false;
}
}
scan.close();
}
}
I dont want the loop to generate, so the user can keep using the program. I tryed some methods of the Scanner but neither of them worked, i dont actually know whats the issue exacty, so... help!
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 am having trouble with entering non-integers into an integer field. I am only taking precautions so that if another person uses/works on my program they don't get this InputMismatchException.
When I enter a non-digit character into the input variable, I get the above error. Is there any way to compensate for this like one could do for a NullPointerException when it comes to strings?
This code is redacted just to include the relevant portions causing the problem.
import java.util.Scanner;
class MyWorld {
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
int input = 0;
System.out.println("What is your age? : ");
input = user_input.nextInt();
System.out.println("You are: " +input+ " years old");
}
}
You can use an if statement to check if user_input hasNextInt(). If the input is an integer, then set input equal to user_input.nextInt(). Otherwise, display a message stating that the input is invalid. This should prevent exceptions.
System.out.println("What is your age? : ");
if(user_input.hasNextInt()) {
input = user_input.nextInt();
}
else {
System.out.println("That is not an integer.");
}
Here is some more information about hasNextInt() from Javadocs.
On a side note, variable names in Java should follow the lowerMixedCase convention. For example, user_input should be changed to userInput.
You can add a try-catch block:
import java.util.Scanner;
class MyWorld {
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
int input = 0;
System.out.println("What is your age? : ");
try{
input = user_input.nextInt();
}catch(InputMisMatchException ex)
System.out.println("An error ocurred");
}
System.out.println("You are: " +input+ " years old");
}
}
If you want to provide the user to enter another int you can create a boolean variable and make a do-while loop to repeat it. As follows:
boolean end = false;
//code
do
{
try{
input = user_input.nextInt();
end = true;
}catch(InputMisMatchException ex)
System.out.println("An error ocurred");
end = false;
System.out.println("Try again");
input.nextLine();
}
}while(end == false);
This is a try-catch block. You need to use this if you want to be sure of not making the program-flow stop.
try {
input = user_input.nextInt();
}
catch (InputMismatchException exception) { //here you can catch that exception, so program will not stop
System.out.println("Integers only, please."); //this is a comment
scanner.nextLine(); //gives a possibility to try giving an input again
}
Test using hasNextInt().
Scanner user_input = new Scanner(System.in);
System.out.println("What is your age?");
if (user_input.hasNextInt()) {
int input = user_input.nextInt();
System.out.println("You are " + input + " years old");
} else {
System.out.println("You are a baby");
}
Use Scanner's next() method to get data instead of using nextInt(). Then parse it to integer using int input = Integer.parseInt(inputString);
parseInt() method throws NumberFormatException if it is not int, which you can handle accordingly.
Goal:
If the user enters a non-numeric number, make the loop run again.
Also is there another (more efficient) way of writing the numeric inputs?
public static void user_input (){
int input;
input = fgetc (System.in);
while (input != '\n'){
System.out.println("Please enter a number: ");
if (input == '0' == '1' ..... '9'){
//Execute some code
}
else {
System.out.println("Error Please Try Again");
//Repeat While loop
}
}
}
EDIT
I need the while loop condition. Simply asking, how do you repeat the while loop? Also no scanner methods.
Take the input using next instead of nextInt. Put a try catch to parse the input using parseInt method. If parsing is successful break the while loop, otherwise continue. Try this:
public static void user_input() {
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("Enter a number.");
String input = sc.next();
int intInputValue = 0;
try {
intInputValue = Integer.parseInt(input);
System.out.println("Correct input, exit");
break;
} catch (NumberFormatException ne) {
System.out.println("Input is not a number, continue");
}
}
}
Output
Enter a number.
w
Input is not a number, continue
Enter a number.
3
Correct input, exit
Try this one
System.out.println("Please enter a number: ");
Scanner userInput = new Scanner(System.in);
while(!userInput.hasNextInt()) {
System.out.println("Invalid input. Please enter again");
userInput = new Scanner(System.in);
}
System.out.println("Input is correct : " + userInput.nextInt());
How about this
public static void processInput() {
System.out.println("Enter only numeric: ");
Scanner scannerInput;
while (true) {
scannerInput = new Scanner(System.in);
if (scannerInput.hasNextInt()) {
System.out.println("Entered numeric is " + scannerInput.nextInt());
break;
} else {
System.out.println("Error Please Try Again");
}
}
}
In school I had to make a calculator program. In the program, we ask the user if they want to add, subtract, multiply, or divide. At the end, we ask the user of they want to continue the program or no. I haven't put in the looping part yet, but my problem here is that after the "Would you like to continue" is displayed, the program just exits.
package calculator;
import java.util.Scanner;
public class calculator {
public static void main(String[] args) {
{
int o1; //first operand
int o2; //second operand
Scanner input = new Scanner (System.in);
System.out.println("Enter a choice:");
System.out.println("+ to add");
System.out.println("- to subtract");
System.out.println("* to multiply");
System.out.println("/ to divide");
System.out.println("X to exit");
String userChoice = input.nextLine();
if (userChoice.equals("X to exit")) {
System.exit(0);
}
System.out.println("Enter the first operand:");
o1 = input.nextInt();
System.out.println("Enter the second operand:");
o2 = input.nextInt();
if (userChoice.equals("+ to add")) {
System.out.println( (o1) + (o2) ); }
else if (userChoice.equals("- to subtract")) {
System.out.println( (o1) - (o2) ); }
else if (userChoice.equals("* to multiply")) {
System.out.println( (o1) * (o2) ); }
else if (userChoice.equals("/ to divide")) {
System.out.println( (o1) / (o2) ); }
System.out.println("Would you like to continue?");
System.out.println("Yes");
System.out.println("No");
String userPick = input.nextLine(); {
if (userPick.equals("Yes")) {
System.out.println("Ok."); }
else if (userPick.equals("No")) {
System.exit(0); }
}
}
}
// TODO Auto-generated method stub
}
Try this:
Scanner input = new Scanner (System.in);
while(true){
System.out.println("Enter a choice:");
System.out.println("+ to add");
......
if (userPick.equals("Yes")) {
System.out.println("Ok."); }
else if (userPick.equals("No")) {
System.exit(0); }
}
}
It will continue to loop around the logic until the terminating condition is met. You may also like to close the scanner before System.exit(); and before any termination in fact.
System.out.println("Would you like to continue?");
System.out.println("Yes");
System.out.println("No");
// add this lline, it can make a difference
input.nextLine();
String userPick = input.nextLine();
You need a while(true) {} loop at the place in the program where you want it to restart. This way, you can go back to the beginning if the user says yes, but the program will exit if the user says no.
You can add a line before your code
String userPick = input.nextLine(); which line is input.nextLine();
it can work well, which can receive enter break line.you can try.
ps:my english is bad,I am not sure I expressed clearly.