How to retry input after an InputMismatchException? - java

I am creating a program that takes input from the user.Now I want to re-run the input option if a user enters an invalid command. Like here only integer input are preferred but if the user inputs text, then I want to catch the exception and rerun the method.
I have tried this but it turns me into an infinite loop.What would be the best way to achieve this. It would be great if someone helps me on this.
boolean retry = true;
while(retry){
try{
//considering response from the user
System.out.print("\nEnter Your Command : ");
f_continue = processresponse(scanner.nextInt());
retry = false;
}catch(InputMismatchException e){
System.err.println("\nPlease Input a Valid Command from 1-5 or 0 for Exit");
}
}

If you enter something other than an integer, nextInt() will throw an exception, and what was entered will still be in the input buffer, so the next time you call nextInt(), you will read the same bad input. You should first call hasNextInt() to see if the input is an integer; if not, just call nextLine() to skip the bad input (and write a message telling the user to re-try).
Or you can just call scanner.nextLine() in the catch block.

Related

Java Scanner.hasNextInt() does not wait for input

I am trying to read only valid integers from the console. I got the example below from another Stackoverflow answer and it should work. If I call the method once it works but on the second call it somehow ignores the sc.hasNextInt() statement and doesn't wait for an input here or thinks there is already an input.
Scanner sc = new Scanner(System.in);
int input;
do {
System.out.println("Please enter a number [0-200]!");
while (!sc.hasNextInt()) {
System.out.println("That's not a number!");
sc.next();
}
input = sc.nextInt();
} while (input >= 0 && input <= 200);
sc.close();
return input;
Example of input:
Please enter a number [0-200]!
d
That's not a number!
-1
Please enter a number [0-200]!
That's not a number!
Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.Scanner.throwFor(Scanner.java:937)
at java.base/java.util.Scanner.next(Scanner.java:1478)
at Aufgabe5.getInput(Aufgabe5.java:44)
at Aufgabe5.main(Aufgabe5.java:112)
nextInt() works in a way that if you input a number and then press Return "The enter key" that key is registered and waiting, when the nextInt() is called again, that registered key will then get consumed by the nextInt() and program will continue without waiting an input, cos it assumed that there was an input. to get around this you can follow the scanner.nextInt() with a scanner.nextLine() to consume that Return key.
other way it can be done by saving a line of code is by replacing scanner.nextInt() with Integer.valueOf(scanner.nextLine()). or better yet, Integer.parseInt(scanner.nextLine())
So apparently removing the sc.close() statement made it work. Idk why though

How do I take input along with handling exceptions?

I want to take an integer input from the user. I am using a try-catch exception so that if the input is not an int it asks the user for another input. I have written the following code:
while (flag==true) {
try {
System.out.println("Enter the encryption key!");
k = input.nextInt();
flag = false;
}
catch (InputMismatchException ex) {
System.out.println("Please enter integer value!(");
}
}
But when an exception occurs the loop keeps on printing
"Enter the encryption key!"
"Please enter integer value!"
infinitely because the scanner input does not wait to take another input.
How can I tackle with this problem?
You could try to use
input.nextLine()
because then it waits until you press enter. But then you need to parse it to an int if i remember correctly.
You should call next inside the catch clause, this will solve the problem.
See the docs - Scanner:
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.
Without having next in the catch clause, input.nextInt(); will keep reading the same token, adding next will consume that token.
You should go with suggestion of Maroun Maroun that looks more clean to me.
One other way is to re-initialize the Scanner in loop.
boolean flag = false;
while (!flag) {
try {
input = new Scanner(System.in);//Initialize it here
//....

Java scanner - can't read user input

I want to read user input like: 11 12 13 14 15 16
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
System.out.println(sc.next());
}
System.out.println("Test");
but it newer goes out of while loop and prints "Test".
How could i read that input?
The method hasNext() works like this:
If it sees the end of the file, it returns false;
If it sees another valid, non-whitespace input, it returns true;
If neither of the above is true, it waits for the next input the user is going to enter, and doesn't return until he does.
Usually, if you use Scanner for files, such a loop will work correctly, because a file has a definite end, and it usually doesn't get stuck waiting for more input.
But when you are working with console input (System.in, not redirected), then usually the user does not send the end-of-file signal. He just presses Return, and so, hasNext() sits and waits to see if the user will enter more input on the next line and so on.
There are two general ways to deal with this:
The user has to actually terminate the input. After you finish entering all your numbers and press Return, you also need to send the end-of-file sequence, which is usually ctrlD or ctrlZ.
If you do that, you will not be able to enter any more input to that program.
The program tells the user to enter some particular value that will tell it that the input is over. For example, the string "DONE". When you do that, you have to change the loop to something like:
String nextInput;
while( sc.hasNext() && ! (nextInput = sc.next()).equals( "DONE" ) ){
System.out.println(nextInput);
}
You can break the loop depending whether you want to quit or not E.g.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String next = sc.next();
if (next.equals("q")) { //if user press q then break the loop
break;
}
System.out.println(next);
}
System.out.println("Test");
}
Use api like:
while(sc.hasNextInt()){
int aba= sc.nextInt();
if (aba == 0) {//or even non numeric value here would let this loop exit
break;
}
}
So you need to enter 0 or even in other way enter non numeric value inorder to come out of loop. nextLine method will read whole line just once and then you will need to parse it and then convert to integer so it's good to use sc.nextInt which will do the work for you.

I need to make Scanner check to see if input is "quit", and then if it's not, accept an integer

I'm trying to write a program that gets an integer from the user, but also ends the program if the user enters "quit". When I run the program, it works when I enter "quit", but when I start entering an integer, I get a blank line. If I enter the integer the second time, it works. I have tried several suggestions that I have found for similar problems - including try/catch, parsing the input to Integer, and firing a blank Scanner#nextLine or Scanner#nextInt (and going back and forth between all of these options). Here is an example of my latest attempt. Any insight would be appreciated.
int colInput;
System.out.println(", please pick a column in which to place your token (1-8).");
System.out.println("(Type 'quit' to exit the game or 'restart' to start over.)");
System.out.print("Column Choice: ");
Scanner selectCol = new Scanner (System.in);
try {
if (selectCol.next().equals("quit"))
Connect4.close();
}
finally {
colInput = selectCol.nextInt();
}
String input = selectCol.next();
int colInput;
if (input.equals("quit"))
Connect4.close();
else
colInput = Integer.parseInt(input);
//Use colInput here or return colInput or whatever you wish to do with it
In the code you mention you are consuming the "next token" found by your scanner in the line
if (selectCol.next().equals("quit"))
the token is received and compared against "quit". No matter what the value of the token originally was it is lost afterwards. Then later in the finally block you ask your scanner for a new token. He is then waiting for a new value from System.in.
To receive the token from the scanner only if it matches "quit" you should change the line to
if (selectCol.next("quit"))
This way you are making use of a method offered by the Scanner class javadoc for next(String).

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.)

Categories

Resources