Catching an InputMismatchException until it is correct [duplicate] - java

This question already has answers here:
How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
(5 answers)
How to use Scanner to accept only valid int as input
(6 answers)
Closed 5 years ago.
I am trying add catch blocks to my program to handle input mismatch exceptions. I set up my first one to work inside of a do while loop, to give the user the opportunity to correct the issue.
System.out.print("Enter Customer ID: ");
int custID=0;
do {
try {
custID = input.nextInt();
} catch (InputMismatchException e){
System.out.println("Customer IDs are numbers only");
}
} while (custID<1);
As it stands, if I try to enter a letter, it goes into an infinite loop of "Customer IDs are numbers only".
How do I make this work properly?

Be aware that When a scanner throws an InputMismatchException, the scanner will not pass the token that caused the exception, so that it may be retrieved or skipped via some other method.
To avoid "infinite loop of "Customer IDs are numbers only".", You need to call input.next(); in the catch statement to to make it possible to re-enter number in Console
From
statement
catch (InputMismatchException e) {
System.out.println("Customer IDs are numbers only");
To
catch (InputMismatchException e) {
System.out.println("Customer IDs are numbers only");
input.next();
}
Example tested:
Enter Customer ID: a
Customer IDs are numbers only
b
Customer IDs are numbers only
c
Customer IDs are numbers only
11

What's happening is that you catch the mismatch, but the number "wrong input" still needs to be cleared and a .next() should be called. Edit: since you also require it to be greater than or equal to 1 per your do/while
boolean valid = false;
while(!valid) {
try {
custID = input.nextInt();
if(custID >= 1) //we won't hit this step if not valid, but then we check to see if positive
valid = true; //yay, both an int, and a positive one too!
}
catch (InputMismatchException e) {
System.out.println("Customer IDs are numbers only");
input.next(); //clear the input
}
}
//code once we have an actual int

Why not use a scanner object to read it with Scanner.readNextInt()?

I got it, this is solution you are looking for:
public class InputTypeMisMatch {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int custID=0;
System.out.println("Please enter a number");
while (!input.hasNextInt()) {
System.out.println("Please enter a number");
input.next();
}
custID = input.nextInt();
}
}

Related

Infinite Loop in My Exception Handling? [duplicate]

This question already has answers here:
How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
(5 answers)
Closed 5 years ago.
I'm trying to validate a user's input on a menu. Options are 1, 2, 3, and 4. I'm trying to handle the InputMismatchException error when they enter in a letter. I can't see what I'm doing wrong to make my code get stuck in an infinite loop.
System.out.println("What will be your starting balance?");
double startingBalance =0;
boolean check = false;
while(!check) {
try {
startingBalance = input.nextDouble();
check = true;
}
catch (InputMismatchException e) {
System.out.println("Invalid input!");
//startingBalance = 0;
//e.printStackTrace();
//check = false;
}
}
It looks like it get into the catch part, but loops through that repeatedly instead of going back to the try. I tried doing input.nextDouble();
to clear input buffer, but did nothing. Any help would be greatly appreciated.
You can use input.nextLine(); to clear your Scanner in your catch block:
while (!check) {
try {
startingBalance = input.nextDouble();
check = true;
} catch (InputMismatchException e) {
System.out.println("Invalid input!");
input.nextLine();//this will clear your Scanner and repeat again
}
}
Can I ask why you used nextLine() as opposed to nextDouble() ?
because nextLine move the Scanner to the next line
you need to set boolean check = false after first check and also use input.nestLine()

Scanner type checking in method [duplicate]

I have read user input that must be only of type int, the problem comes when the user enters letter instead of a int. I know how to handle the exception, but I would like to return the scanner read where the user has made a mistake. How can I do?
I already tried with an infinite loop, but it does not work.
try{
System.out.print("enter number: ");
value = scanner.nextInt();
}catch(InputMismatchException e){
System.err.println("enter a number!");
}
While other answers give you correct idea to use loop you should avoid using exceptions as part of your basic logic. Instead you can use hasNextInt from Scanner to check if user passed integer.
System.out.print("enter number: ");
while (!scanner.hasNextInt()) {
scanner.nextLine();// consume incorrect values from entire line
//or
//tastiera.next(); //consume only one invalid token
System.out.print("enter number!: ");
}
// here we are sure that user passed integer
int value = scanner.nextInt();
A loop is the right idea. You just need to mark a success and carry on:
boolean inputOK = false;
while (!inputOK) {
try{
System.out.print("enter number: ");
numAb = tastiera.nextInt();
// we only reach this line if an exception was NOT thrown
inputOK = true;
} catch(InputMismatchException e) {
// If tastiera.nextInt() throws an exception, we need to clean the buffer
tastiera.nextLine();
}
}

Back scanner reading after user error - java

I have read user input that must be only of type int, the problem comes when the user enters letter instead of a int. I know how to handle the exception, but I would like to return the scanner read where the user has made a mistake. How can I do?
I already tried with an infinite loop, but it does not work.
try{
System.out.print("enter number: ");
value = scanner.nextInt();
}catch(InputMismatchException e){
System.err.println("enter a number!");
}
While other answers give you correct idea to use loop you should avoid using exceptions as part of your basic logic. Instead you can use hasNextInt from Scanner to check if user passed integer.
System.out.print("enter number: ");
while (!scanner.hasNextInt()) {
scanner.nextLine();// consume incorrect values from entire line
//or
//tastiera.next(); //consume only one invalid token
System.out.print("enter number!: ");
}
// here we are sure that user passed integer
int value = scanner.nextInt();
A loop is the right idea. You just need to mark a success and carry on:
boolean inputOK = false;
while (!inputOK) {
try{
System.out.print("enter number: ");
numAb = tastiera.nextInt();
// we only reach this line if an exception was NOT thrown
inputOK = true;
} catch(InputMismatchException e) {
// If tastiera.nextInt() throws an exception, we need to clean the buffer
tastiera.nextLine();
}
}

Java Scanner receives nonexistent input

I have a loop which breaks upon receiving the correct input from the console. I am using Scanner to read in a String from System.in, which seems to be what's giving me trouble. Here is my code:
boolean loop = true;
while(loop) {
try {
System.out.println("Enter an input (\"input a\" or \"input b\"): ");
String input = scanner.nextLine();
System.out.println("");
if (input.equals("input a")) {
System.out.println("Answer to input a.");
} else if (input.equals("input b")) {
System.out.println("Answer to input b.");
} else {
throw new IllegalArgumentException();
}
loop = false;
} catch (InputMismatchException e) {
System.out.println(e.getMessage());
System.out.println("");
} catch (IllegalArgumentException e) {
System.out.println("Input not recognized. Please enter a valid input.");
System.out.println("");
}
}
When this is called, it loops once without even waiting for input from the user, then actually stops and does what it is supposed to the second time around. IE, the output for this, without the user giving any input at all, is:
Enter an input ("input a" or "input b"):
Input not recognized. Please enter a valid input.
Enter an input ("input a" or "input b"):
If I give it a bad input (so that it loops and asks again), it does the same thing where it loops twice before waiting. I have no idea why.
Why is this happening, and what should I do to avoid it?
EDIT: Test scenarios after hasNext check:
Scenario A:
Enter an input ("input a" or "input b"): input a //my input
Input not recognized. Please enter a valid input.
Enter an input ("input a" or "input b"): //no input given here
Answer to input a.
Scenario B:
Enter an input ("input a" or "input b"): ddd //my input
Input not recognized. Please enter a valid input.
Enter an input ("input a" or "input b"): //no input given here
Input not recognized. Please enter a valid input.
Enter an input ("input a" or "input b"): input b //my input
Answer to input b.
The code which produces this:
boolean loop = true;
while(loop) {
if (scanner.hasNext()) {
try {
System.out.println("Enter an input (\"input a\" or \"input b\"): ");
String input = scanner.nextLine();
System.out.println("");
if (input.equals("input a")) {
System.out.println("Answer to input a.");
} else if (input.equals("input b")) {
System.out.println("Answer to input b.");
} else {
throw new IllegalArgumentException();
}
loop = false;
} catch (InputMismatchException e) {
System.out.println(e.getMessage());
System.out.println("");
} catch (IllegalArgumentException e) {
System.out.println("Input not recognized. Please enter a valid input.");
System.out.println("");
}
}
}
I tried out the code you've wrote down in your question, as a single question, but I can't find any problem with it at all. However, I think I know just the answer.
If you did any other input before this with primitive types or just next(), you need to flush the newline character that unfortunately those next methods leave behind. To do this, just call "scanner.nextLine()" before the statement where the method returns the inputted string and assigns it to input.
You want to make sure that you call in the method as separate; you know, on its own. It's best if you put it in your while loop at the top before you enter so that way for every iteration, the newline character is cleared. The statement will then get rid of the newline character and thus the input buffer is empty. Once that's cleared out, you can finally input your string at your first loop iteration.
How's that for an answer? Try it out and let me know if it works!
You should first check if the user has enetered any data :
if(scanner.hasNext())
{
// code logic
}

Scanner.reset() doesn't work

This piece of code is supposed to get an integer number from user and then finish the program. If the user inputs an invalid number, it asks user again.
After catching exception, it uses Scanner.reset() to reset the scanner, but it doesn't work. and it re-throws previous exception.
Scanner in = new Scanner(System.in);
while (true) {
try {
System.out.print("Enter an integer number: ");
long i = in.nextLong();
System.out.print("Thanks, you entered: ");
System.out.println(i);
break;
} catch (InputMismatchException ex) {
System.out.println("Error in your input");
in.reset(); // <----------------------------- [The reset is here]
}
}
I thought Scanner.reset() will reset everything and forget the exception. I put it before asking the user for a new input.
If I get the point wrong, what is the right way?
You misunderstood the purpose of the reset method: it is there to reset the "metadata" associated with the scanner - its whitespace, delimiter characters, and so on. It does not change the state of its input, so it would not achieve what you are looking for.
What you need is a call of next(), which reads and discards any String from the Scanner:
try {
System.out.print("Enter an integer number: ");
long i = in.nextLong();
System.out.print("Thanks, you entered: ");
System.out.println(i);
break;
} catch (InputMismatchException ex) {
System.out.println("Error in your input");
in.next(); // Read and discard whatever string the user has entered
}
Relying upon exceptions to catch exceptional situations is OK, but an even better approach to the same issue would be using has... methods before calling the next... methods, like this:
System.out.print("Enter an integer number: ");
if (!in.hasNextLong()) {
in.next();
continue;
}
long i = in.nextLong();
System.out.print("Thanks, you entered: ");
System.out.println(i);
break;
Per Scanner.reset() javadoc, the method only "resets" locale, radix and delimiter settings. It does not do anything to the data it already read.

Categories

Resources