While loop with try/catch causes endless loop - java

The code snippet below causes an endless loop, when I enter a character. That's really weird for me, for a wrong number it works fine, but when I am entering any character, it causes an endless loop.
boolean checkValue = false;
Scanner console = new Scanner(System.in);
while (!checkValue) {
System.out.println("Enter 1, 2 or 3");
try {
input = console.nextInt();
switch (input) {
case 1:
// code
checkValue = true;
break;
case 2:
// code
checkValue = true;
break;
case 3:
// code
checkValue = true;
break;
default: // when entered a wrong number
System.err.println("Wrong Input");
checkValue = false;
}
}
catch(Exception e) { // when entered a character
System.err.println("Wrong Input");
checkValue = false;
}
}

You need to check for the right type of the input, instead of trying to catch an exception. When you find the wrong input has been supplied, you have to consume the input in order to proceed to the next try. Like so:
public static void main(String[] args) {
boolean checkValue = false;
int input;
Scanner console = new Scanner(System.in);
while (!checkValue) {
System.out.println("Enter 1, 2 or 3");
// Check if we have an integer
if (console.hasNextInt()) {
input = console.nextInt();
switch (input) {
case 1:
// code
checkValue = true;
break;
case 2:
// code
checkValue = true;
break;
case 3:
// code
checkValue = true;
break;
default: // when entered a wrong number
System.err.println("Wrong Input");
checkValue = false;
}
}
else {
// when entered a character
System.err.println("Wrong Input");
// Consume the wrong input.
console.next();
checkValue = false;
}
}
}

You assign the input into one variable :
input = console.nextInt();
But the switch statement tests a different variable :
switch (auswahl) {
EDIT :
Add console.nextLine() to your exception handler, to consume the end of the current line, to allow the next nextInt to read from the next line.

What's "auswha1" ? Its value is not updated and your scanner is outside the loop.
Moreover, are you sure that you are testing a character in your switch ? It looks like an int.
Edit :
Instantiate a new scanner before calling nextInt, it should work :
try {
Scanner console = new Scanner(System.in);
int input = console.nextInt();
switch (input) {
...

Since you use console.nextInt(), you will read only integers on the input. Then, when you enter something which is not an int, you catch an Exception. There you need to consume the bad input, e.g. with a nextLine():
catch(Exception e) { // when entered a character
System.err.println("Wrong Input");
checkValue = false;
console.nextLine(); // <=== add
}
Then it works...

You probably get java.util.InputMismatchException after inputting any illegal character. It does not clear the input buffer, so calling nextInt() causes the same error etc.
Add console.next(); to the catch clause to skip the wrong character.

auswahl variable is not assigned with your input. Actually speaking this variable is not even in scene till you use it in switch.
boolean checkValue = false;
int input;
Scanner console = new Scanner(System.in);
while (!checkValue) {
System.out.println("Enter 1, 2 or 3");
try {
input = console.nextInt();
switch (input) {
case 1:
// code
checkValue = true;
break;
case 2:
// code
checkValue = true;
break;
case 3:
// code
checkValue = true;
break;
default: // when entered a wrong number
System.err.println("Wrong Input");
checkValue = false;
}
}
catch(Exception e) { // when entered a character
System.err.println("Wrong Input");
checkValue = false;
}
System.out.println("Program Ends");

This will work
catch (Exception e) { // when entered a character
System.err.println("Wrong Input");
checkValue = false;
console = new Scanner(System.in);//Edit
}

boolean checkValue = true;
Scanner console = new Scanner(System.in);
while (checkValue) {
System.out.println("Enter 1, 2 or 3");
try {
input = console.nextInt();
switch (input) {
case 1:
// code
checkValue = false;
break;
case 2:
// code
checkValue = false;
break;
case 3:
// code
checkValue = false;
break;
default: // when entered a wrong number
System.err.println("Wrong Input");
checkValue = false;
}
}
catch(Exception e) { // when entered a character
System.err.println("Wrong Input");
checkValue = false;
}
}

Related

Scanner inputMismatch

This is my code (simplified).
public class A {
int num;
public void method () {
Scanner scanner = new Scanner(System.in);
num = scanner.nextInt();
switch (num) {
case 1:
System.out.println("Hello 1");
scanner.close();
break;
case 2:
System.out.println("Hello 2");
scanner.close();
break;
case 3:
System.out.println("Hello 3");
scanner.close();
break;
default:
System.out.println("\nPlease try again.");
method();
}
}
}
I want any non-integer input like Strings to also run the default case and sysout the "Please try again" instead of getting an inputMismatch error, but i have no idea how to do it.
Basically any input that is not a 1,2 or 3 should jump to the default case.
You can't do this through this code as you are taking user input as integer and if you will enter a string it will through inputMismatch error as the compiler is expecting integer but getting string or character input.
Now what you can do is take a string as the user input. Here the complete code for you:
public class A {
String num;
public void method () {
Scanner scanner = new Scanner(System.in);
num = scanner.nextLine();
switch (num) {
case "1":
System.out.println("Hello 1");
scanner.close();
break;
case "2":
System.out.println("Hello 2");
scanner.close();
break;
case "3":
System.out.println("Hello 3");
scanner.close();
break;
default:
System.out.println("\nPlease try again.");
method();
}
}
}
This is what you want. It will work for every input.
Use scanner.hasNextInt() to check if the input is an integer. If not, assign zero to num which then results in matching the default.
You can't get strings by num = scanner.nextInt();. But, I have an idea.
value = scanner.nextLine();
//Now, check it is string or int
boolean numeric = true;
try {
Double num = Double.parseDouble(value);
} catch (NumberFormatException e) {
numeric = false;
}
if(numeric){
Integer.parseInt(value)
}else{
//you can write value= value. Or, you can left it empty also. Or, you can remove else statement also.
}
switch (num) {
case 1:
System.out.println("Hello 1");
scanner.close();
break;
case 2:
System.out.println("Hello 2");
scanner.close();
break;
case 3:
System.out.println("Hello 3");
scanner.close();
break;
case "Hello":
System.out.println("Hello 3");
scanner.close();
break;
default:
System.out.println("\nPlease try again.");
method();
}
#Badal is correct also. And, I did it with keeping int value. And, I don't remember is there any other way to check is it string or not. So, Sorry.

Stuck in Infinite loop, why it does not wait for scanner to re-enter the values [duplicate]

my question is short and sweet. I do not understand why my program infinitely loops when catching an error. I made a fresh try-catch statement but it looped and even copied, pasted and modified the appropriate variables from a previous program that worked. Below is the statement itself and below that will be the entire program. Thank you for your help!
try {
input = keyboard.nextInt();
}
catch(Exception e) {
System.out.println("Error: invalid input");
again = true;
}
if (input >0 && input <=10)
again = false;
}
Program:
public class Blanco {
public static int input;
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
nameInput();
}
/**
*
* #param name
*/
public static void nameInput() {
System.out.println("What is the name of the cartoon character : ");
Scanner keyboard = new Scanner(System.in);
CartoonStar star = new CartoonStar();
String name = keyboard.next();
star.setName(name);
typeInput(keyboard, star);
}
public static void typeInput(Scanner keyboard, CartoonStar star) {
boolean again = true;
while(again){
System.out.println("What is the cartoon character type: 1 = FOX,2 = CHICKEN,3 = RABBIT,4 = MOUSE,5 = DOG,\n"
+ "6 = CAT,7 = BIRD,8 = FISH,9 = DUCK,10 = RAT");
try {
input = keyboard.nextInt();
}
catch(Exception e) {
System.out.println("Error: invalid input");
again = true;
}
if (input >0 && input <=10)
again = false;
}
switch (input) {
case 1:
star.setType(CartoonType.FOX);
break;
case 2:
star.setType(CartoonType.CHICKEN);
break;
case 3:
star.setType(CartoonType.RABBIT);
break;
case 4:
star.setType(CartoonType.MOUSE);
break;
case 5:
star.setType(CartoonType.DOG);
break;
case 6:
star.setType(CartoonType.CAT);
break;
case 7:
star.setType(CartoonType.BIRD);
break;
case 8:
star.setType(CartoonType.FISH);
break;
case 9:
star.setType(CartoonType.DUCK);
break;
case 10:
star.setType(CartoonType.RAT);
break;
}
popularityNumber(keyboard, star);
}
public static void popularityNumber(Scanner keyboard, CartoonStar star) {
System.out.println("What is the cartoon popularity number?");
int popularity = keyboard.nextInt();
star.setPopularityIndex(popularity);
System.out.println(star.getName() + star.getType() + star.getPopularityIndex());
}
}
Your program runs forever because calling nextInt without changing the state of the scanner is going to cause an exception again and again: if the user did not enter an int, calling keyboard.nextInt() will not change what the scanner is looking at, so when you call keyboard.nextInt() in the next iteration, you'll get an exception.
You need to add some code to read the garbage the user entered after servicing an exception to fix this problem:
try {
...
} catch(Exception e) {
System.out.println("Error: invalid input:" + e.getMessage());
again = true;
keyboard.next(); // Ignore whatever is entered
}
Note: you do not need to rely on exceptions in this situation: rather than calling nextInt(), you could call hasNextInt(), and check if the scanner is looking at an integer or not.

Loop back to program after an exception is thrown

public void runMenu() {
int x = 1;
Scanner Option = new Scanner (System.in);
int Choice = 0;
do {
try {
System.out.println("Choose Option");
System.out.println("");
System.out.println("1: Create Account");
System.out.println("2: Check Account");
System.out.println("3: Take Action");
System.out.println("4: Exit");
System.out.println("Please choose");
Choice = Option.nextInt();
switch (Choice) { //used switch statement instead of If else because more effective
case 1:
CreateAccount();
break; //breaks iteration
case 2:
selectAccount();
break;
case 3:
Menu();
int choice = UserInput();
performAction(choice);
break;
case 4:
System.out.println("Thanks for using the application");
System.exit(0);
default:
System.out.println("Invalid Entry");
throw new Exception();
}
} catch (Exception e) {
System.err.println("Enter Correct Input");
return;
}
} while (true);
}
I am trying to make it when users enter incorrect input type like a letter , the exception is caught and then returns back to the menus, right now it catches the exception but it doesnt stop running I have to force stop the program. So I added a return but that just displays the exception error and stops, how can I make it return back to the menus?
That is because you're returning from the method itself in the catch block.
And Do not throw exceptions like that. Just use some boolean to know if the choice is valid and loop until the choice is entered correctly.Prefer not to use while(true), instead rely on a boolean flag everytime like below,
public void runMenu() {
int x = 1;
Scanner Option = new Scanner (System.in);
int Choice = 0;
boolean isValidChoice = false;
do{
isValidChoice = false;
Choice = 0;
System.out.println("Choose Option");
System.out.println("");
System.out.println("1: Create Account");
System.out.println("2: Check Account");
System.out.println("3: Take Action");
System.out.println("4: Exit");
System.out.println("Please choose");
if(Option.hasNextInt()){
Choice= Option.nextInt();
isValidChoice = true;
}
switch (Choice)
{
case 1:
CreateAccount();
break;
case 2:
selectAccount();
break;
case 3:
Menu();
int choice = UserInput();
performAction(choice);
break;
case 4:
System.out.println("Thanks for using the application");
System.exit(0);
default:
isValidChoice = false; //if invalid choice, then set flag to loop
System.out.println("Invalid Entry");
}
} while (!isValidChoice);
}
Move the "try {" after the "System.out.println("Please choose");" line.
you just need to remove the return in the catch. also just as a tip, you can get rid of the do while and just have a while loop, because the loop is never ending.
} catch (Exception e) {
System.err.println("Enter Correct Input");
}
Okay so I'm pretty sure this should work:
Create a boolean value outside of while loop that is holds if there was a valid input
boolean validInput = true;
In default set this value to false (meaning there is an invalid input)
default:
System.out.println("Invalid Entry");
validInput = false;
throw new Exception();
Make sure the catch statement is still in the do loop because the throw clause will halt normal execution and transition into exception execution. Next the while tester will test if there was a valid input
while(!validInput)
Lastly go up to the top of the do loop and set validInput to true. This will make it so that each time you clear the previous incorrect input.
This should work.

How to go back to the "try" code everytime the input is not correct (in Java)?

I want the program to retry the "try" part of the code every time the input is incorrect and throws an error(which is solved with an exception).
My code looks like this:
try {
System.out.print("Enter a number from 1 to 3: ");
enteredNumber = userInputScanner.nextInt();
makeHumanMove(enteredNumber);
}catch(Exception e){
System.out.println("Incorrect input!");
My "makeHumanMove" function checks, if the number is from 1 to 3.. But if the user inserts a letter, it would throw an error and if it happens, I want the program to ask for another input until the user inserts a correct input.
I've tried while and for loops but I keep messing up. Any ideas?
How's about this code:
while (true) {
try {
System.out.print("Enter a number from 1 to 3: ");
enteredNumber = userInputScanner.nextInt();
makeHumanMove(enteredNumber);
break;
}catch(Exception e){
System.out.println("Incorrect input!");
}
}
Make sure that your makeHumanMove(enteredNumber); throws new Exception();
boolean inputIsCorrect = false;
while(inputIsCorrect == false){
try {
System.out.print("Enter a number from 1 to 3: ");
enteredNumber = userInputScanner.nextInt();
makeHumanMove(enteredNumber);
inputIsCorrect = true;
}catch(Exception e){
System.out.println("Incorrect input!");
}
}
This, of course, assumes that your makeHumanMove method throws an exception.
If I was doing this, I don't think I would be using exceptions. My code would be more like ...
boolean inputIsCorrect = false;
while(inputIsCorrect == false){
System.out.print("Enter a number from 1 to 3: ");
enteredNumber = userInputScanner.nextInt();
inputIsCorrect = makeHumanMove(enteredNumber);
}
I'd change the makeHumanMove return a value that indicates whether the the inout is valid or not, rather than using exceptions. ( Can't remember if scanner.nextInt() throws exception .... )
Use a boolean value outside, set it to true at the end of the try block. Then you can test for it using a while loop.
int enteredNumber;
boolean correctNumber = false;
while (!correctNumber) {
try {
System.out.print("Enter a number from 1 to 3: ");
enteredNumber = userInputScanner.nextInt();
makeHumanMove(enteredNumber);
correctNumber = true;
}catch(Exception e){
System.out.println("Incorrect input!");
}
}
Note that you should not use exceptions at all to report incorrect input. You should test for incorrect input and abort early. You should also consider if makeHumanMove should actually be part of the try/catch block; input validation should not be part of the business logic of your application.
final int number;
System.out.print("Enter a number from 1 to 3: ");
while (true) {
int enteredNumber;
try {
enteredNumber = userInputScanner.nextInt();
} catch (Exception e) {
System.out.print("Not a number, enter a number from 1 to 3: ");
userInputScanner = new Scanner(System.in);
continue;
}
if (enteredNumber < 1 || enteredNumber > 3) {
System.out.print("Incorrect number, enter a number from 1 to 3: ");
continue;
} else {
number = enteredNumber;
break;
}
}
makeHumanMove(number);

.hasNextInt() in switch statement

I'm basically trying to validate so that you can only enter an Integer. This is what I have at the moment, but if I type letters it goes through the switch and just leaves the result as blank.
I want it so that if anything other than an integer is entered it will go to default in the switch.
Any help would be great. Thanks!
while(loop && kb.hasNextInt())
{
choice = kb.nextInt();
switch(choice)
{
case 1 :
language = "FRENCH";
loop = false;
break;
case 2 :
language = "GERMAN";
loop = false;
break;
case 3 :
language = "SPANISH";
loop = false;
break;
default :
System.out.println("That is not a correct choice. Please try again!");
break;
}
}
If the next input is not an integer,
then .hasNextInt() will return false,
and therefore the loop will terminate early.
If you want to allow text input and respond to it,
then you need to read line by line, text instead of numbers,
and parse the line read with Integer.parseInt.
If the line cannot be parsed, you will get a NumberFormatException.
You can catch it, and handle appropriately.
while (loop && scanner.hasNextLine()) {
String line = scanner.nextLine();
try {
choice = Integer.parseInt(line);
} catch (NumberFormatException e) {
System.out.println("That is not an integer. Please try again!");
continue;
}
switch (choice) {
case 1:
language = "FRENCH";
loop = false;
break;
case 2:
language = "GERMAN";
loop = false;
break;
case 3:
language = "SPANISH";
loop = false;
break;
default:
System.out.println("That is not a correct choice. Please try again!");
break;
}
}
This is because a letter will cause your while(loop && kb.hasNextInt()) to be false. I suggest put an if statement with the hasNextInt() within the while loop.
Example (using a while loop instead of if statement to really try getting the number):
while(loop)
{
// validate int using while loop
while(!kb.hasNextInt())
{
System.out.println("you must enter a number! ");
kb.next();
}
choice = kb.nextInt();
switch(choice)
{
case 1 :
language = "FRENCH";
loop = false;
break;
case 2 :
language = "GERMAN";
loop = false;
break;
case 3 :
language = "SPANISH";
loop = false;
break;
}
}
System.out.println("Thank You " + studentID + " you have been registered for " + language);
This code will blow before it even begins if the user did not enter a number as the while required kb.hasNextInt() to be true (have a number) to even run.
What I do is that I usually put the validation around where I receive the input:
int choice;
Boolean retry = null;
while(retry == null) {
try{
String input = scanner.nextLine();
choice = Integer.parseInt(input);
retry = false;
}catch(NumberFormatException e){
System.out.println("Please enter a number from 1 to 4.");
}
}
switch(choice){
case 1:
// Do stuff
break;
case 2:
// Do stuff
break;
case 3:
// Do stuff
break;
case 4:
// Do stuff
break;
default:
System.out.println("Something went wrong!");
}

Categories

Resources