Java.util.scanner error handling - java

I'm helping a friend with a java problem. However, we've hit a snag. We're using Java.Util.Scanner.nextInt() to get a number from the user, asking continiously if the user gives anything else. Only problem is, we can't figure out how to do the error handeling.
What we've tried:
do {
int reloop = 0;
try {
number = nextInt();
} catch (Exception e) {
System.out.println ("Please enter a number!");
reloop ++;
}
} while(reloop != 0);
Only problem is, this loops indefinatly if you enter in something not a number.
Any help?

You can use hasNextInt() to verify that the Scanner will succeed if you do a nextInt(). You can also call and discard nextLine() if you want to skip the "garbage".
So, something like this:
Scanner sc = new Scanner(System.in);
while (!sc.hasNextInt()) {
System.out.println("int, please!");
sc.nextLine();
}
int num = sc.nextInt();
System.out.println("Thank you! (" + num + ")");
See also:
How do I keep a scanner from throwing exceptions when the wrong type is entered? (java)
The problem with your code, in addition to the unnecessarily verbose error handling because you let nextInt() throw an InputMismatchException instead of checking for hasNextInt(), is that when it does throw an exception, you don't advance the Scanner past the problematic input! That's why you get an infinite loop!
You can call and discard the nextLine() to fix this, but even better is if you use the exception-free hasNextInt() pre-check technique presented above instead.

if the number is non-int , exception will pop, if not reloop will become 1 , and loop will exit
int reloop = 0;
do {
try {
number = nextInt();
reloop ++;
} catch (Exception e) {
System.out.println ("Please enter a number!");
}}
while(reloop == 0);

Related

If isNaN not throwing non Double inputs

I don't know if im using the isNaN right but can you guys help me on using it to accept only numbers in inputs
while (true){
System.out.println("first number");
num1=input.nextDouble();
if (num1.isNaN()){
System.out.println("invalid input");
}
else;
break;
}
My issue is that when i input a letter, it is not displaying the invalid input message. It just stops the program because i input a letter which is not the error i want to see
Scanner does not return a NaN when an invalid input is given. Instead it throws an InputMismatchException. You could use a try-catch statement to catch this exception and handle it appropriately.
Alternatively, Scanner also has a hasNextDouble() function. This waits and checks if the next value is valid as a double, without actually consuming it.
So you could write your loop like this:
while (true){
System.out.println("Please input a number:");
if (!input.hasNextDouble()) {
System.out.println("Not a valid number.");
break;
}
double number = input.nextDouble();
System.out.println("Your input: " + number);
}
See the documentation on Scanner.hasNextDouble

Java: Program crashes after inputting two bad values

I coded a program, that calculates the gcd (greatest common divisor) and lcm (least common multiple). Everything works fine except the try {...} catch(...) {...}. Here is the part of the code that doesn't work as I want it to:
try {
num1 = Integer.parseInt(sc.nextLine());
}
catch(Exception e) {
System.out.println("Your input is not an integer (number w/o decimals)! Try again.");
System.out.print("Enter your first number: ");
num1 = Integer.parseInt(sc.nextLine());
}
When I input e.g. letters, it says:
Your input is not an integer (number w/o decimals)! Try again.
Enter your first number:
But when I type letters the second time, the program crashes:
Exception in thread "main" java.lang.NumberFormatException: For input string: "asdf"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)
at java.base/java.lang.Integer.parseInt(Integer.java:658)
at java.base/java.lang.Integer.parseInt(Integer.java:776)
at GCDLCMgetter.main(GCDLCMgetter.java:56)
It is probably a very simple mistake I made but I can't figure it out...
Thank you
Your second parseInt method call is not in try catch block. You need to use a loop for this kind of logic.
It's because your second prompt is inside the catch block. Instead of prompting again inside the catch block, you want to wrap the entire code section in a loop so it comes back around to the try block for the prompt again.
Something like:
boolean repeat = true;
while(repeat){
try{
//Prompt for input
repeat = false;
}catch(Exception e) {
//Display error message
}
}
When the first time you give letters it goes into catch block. Displays the error message. And then executes the line num1 = Integer.parseInt(sc.nextLine());
Again you have entered the letters, but this time there is no try-catch block to handle this. So it throws error.
In your code, it gets executed twice:
Reads a Line at try{...}
There is an Exception
The Exception is handled by the catch(Exception e){...}
The num1 = Integer.parseInt(sc.nextLine()); inside the catch(Exception e){...} cannot be handled. It's not placed inside try{}.
Execution finished because the last exception cannot be handled by any catch.
It seems you're using Scanner, I would recommend you using a loop whis way:
while (sc.hasNextLine()){
try {
System.out.print("Enter your first number: ");
num1 = Integer.parseInt(sc.nextLine());
}
catch(Exception e) {
System.out.println("Your input is not an integer (number w/o decimals)! Try again.");
}
}
If you're managing integers, it would be interesting using Scanner.nextInt()
while (sc.hasNextInt()){
try {
System.out.print("Enter your first number: ");
num1 = sc.nextInt());
}
catch(Exception e) {
System.out.println("Your input is not an integer (number w/o decimals)! Try again.");
}
}

InputMismatchException...even with try/catch

So I'm writing code here just for fun but I've come up with an error that I just can't seem to fix. This block of code is supposed to take in an int... at first i had the hasNextInt() in the while loop alone to try and ensure i'm getting the correct input, but as fate would have it.. i got the exception. I then added a try catch to it thinking maybe i just did something wrong... and still i get the same error. I don't know whats wrong here. this is actually my 1st time using a try catch block (still kind of a noob). it looks good to me and i've looked at the documentation online and done some minor research but to no avail. can anyone identify whats wrong here?
check it out:
do{
System.out.println("How much AP do you want to allocate towards HP? ");
try {//added try catch... still throwing the exception..
while(!in.hasNextInt()){//this should've been enough, apparently not
System.out.println("That is not a valid input, try again.");
in.nextInt();
}
} catch (InputMismatchException e) {
System.out.print(e.getMessage()); //trying to find specific reason.
}
hpInput = in.nextInt();
}while(hpInput < 0 || hpInput > AP);
if i entered a string it would give me the "That is not a valid input, try again." line.. but the exception would still occur right after instead of just looping until an actual int is detected... help plz..
Your while loop should look something like this
while(!in.hasNextInt()){ // <-- is there an int?
System.out.println("That is not a valid input, try again.");
// in.nextInt(); // <-- there is not an int...
in.next(); // <-- this isn't an int.
}
Because the Scanner doesn't have an int.
You can't really validate the value in the Scanner until something has been input, but once it's input, it's too late to validate it...
Instead, you could use a second Scanner to validate the String result you are getting from the user via the keyboard, for example
Scanner kbd = new Scanner(System.in);
int result = -1;
do {
System.out.println("How much AP do you want to allocate towards HP? ");
String value = kbd.nextLine();
Scanner validate = new Scanner(value);
if (validate.hasNextInt()) {
result = validate.nextInt();
}
} while (result < 0);

try/catch infinite loop? [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.
Help, I am completely new to java and I am trying to create a loop that will ask for an input from the user which is to be a number. If the user enters anything other than a number I want to catch the exception and try again to get the correct input. I did this with a while loop however it does not give the opportunity after the error for the user to type in anything it loops everything else but that. Please help me to see understand what is wrong and the correct way to do this... Thank you. This is what I have:
import java.util.Scanner;
import java.util.InputMismatchException;
public class simpleExpressions {
public static void main (String[] args) {
Scanner keyboard = new Scanner(System.in);
while ( true ) {
double numOne;
System.out.println("Enter an Expression ");
try {
numOne = keyboard.nextInt();
break;
} catch (Exception E) {
System.out.println("Please input a number only!");
} //end catch
} //end while
} //end main
while ( true )
{
double numOne;
System.out.println("Enter an Expression ");
try {
numOne = keyboard.nextInt();
break;
}
catch (Exception E) {
System.out.println("Please input a number only!");
}
This suffers from several problems:
numOne hasn't been initialized in advance, so it will not be definitely assigned after the try-catch, so you won't be able to refer to it;
if you plan to use numOne after the loop, then you must declare it outside the loop's scope;
(your immediate problem) after an exception you don't call scanner.next() therefore you never consume the invalid token which didn't parse into an int. This makes your code enter an infinite loop upon first encountering invalid input.
Use keyboard.next(); or keyboard.nextLine() in the catch clause to consume invalid token that was left from nextInt.
When InputMismatchException is thrown Scanner is not moving to next token. Instead it gives us opportunity to handle that token using different, more appropriate method like: nextLong(), nextDouble(), nextBoolean().
But if you want to move to other token you need to let scanner read it without problems. To do so use method which can accept any data, like next() or nextLine(). Without it invalid token will not be consumed and in another iteration nextInt() will again try to handle same data throwing again InputMismatchException, causing the infinite loop.
See #MarkoTopolnik answer for details about other problems in your code.
You probably want to use a do...while loop in this case, because you always want to execute the code in the loop at least once.
int numOne;
boolean inputInvalid = true;
do {
System.out.println("Enter an expression.");
try {
numOne = keyboard.nextInt();
inputInvalid = false;
} catch (InputMismatchException ime) {
System.out.println("Please input a number only!");
keyboard.next(); // consume invalid token
}
} while(inputInvalid);
System.out.println("Number entered is " + numOne);
If an exception is thrown then the value of inputInvalid remains true and the loop keeps going around. If an exception is not thrown then inputInvalid becomes false and execution is allowed to leave the loop.
(Added a call to the Scanner next() method to consume the invalid token, based on the advice provided by other answers here.)

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