I am trying to implement a (re)try-catch block.
Scanner sc = new Scanner(System.in);
while (true){
try {
t = sc.nextInt();
break;
} catch (Exception e) {
System.out.println("Please enter a whole number without any symbol(s)!");
}
}
But the problem here is that the control again goes into the catch block ones it reaches there and never attempts to execute the try block before that.
Here's how I solved it...
/*java.util.*/Scanner sc = new /*java.util.*/Scanner(System.in);
while(true)
{
if(sc.hasNextInt()){ t=sc.nextInt(); break;}
System.out.println("Please enter a whole number integer (between -2,147,483,649 and 2,147,483,648) without any symbol(s)!");
sc.nextLine(); // hasNextInt() only scans the current line in the buffer
}
Related
I want to ask the user to enter a String, and four integer values, and i want the program to keep asking the user for integer value if the user input a type mismatch, why the code keep looping forever and never wait for the user input if the user inserted a wrong type ?
import java.util.InputMismatchException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String sessionName;
int pomoInterv, breakInterv, terminalBreakInterv;
System.out.println("Please, Enter the session name: ");
sessionName = scanner.nextLine();
while (true) {
try {
System.out.println("Please, Enter the Pomodoro interval: ");
pomoInterv = scanner.nextInt();
break;
} catch (InputMismatchException ex) {
System.out.println(ex.getMessage());
}
}
while (true) {
try {
System.out.println("Please, Enter the break interval: ");
breakInterv = scanner.nextInt();
break;
} catch (InputMismatchException ex) {
System.out.println(ex.getMessage());
}
}
while (true){
try {
System.out.println("Please, Enter the terminal break interval ");
terminalBreakInterv = scanner.nextInt();
break;
} catch (InputMismatchException ex) {
System.out.println(ex.getMessage());
}
}
System.out.println("Done!");
System.out.println(sessionName);
System.out.println(pomoInterv);
System.out.println(breakInterv);
System.out.println(terminalBreakInterv);
}
}
According to scanner oracle docs :
https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html
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.
So when you entered anything other than an integer, the scanner.nextInt() will not parse it to integer and throw InputMismatchException and the scanner will not move to the next token and tried to read again and again the same token.
To solve this, you can either change the loop or use hasNextInt() method or use scanner.next() in the catch block so that the scanner can move to the next token.
I always use do-while loop when checking for correct Input from the user.
See if the following works:
Scanner scanner = new Scanner(System.in);
String sessionName;
int pomoInterv = -1, breakInterv = -1, terminalBreakInterv = -1;
System.out.println("Please, Enter the session name: ");
sessionName = scanner.nextLine();
boolean isPomoInterv = false;
do {
System.out.println("Please, Enter the Pomodoro interval: ");
String temp = scanner.nextLine();
try {
if (Integer.parseInt(temp) > 0) {
pomoInterv = Integer.parseInt(temp);
isPomoInterv = true;
}
} catch (NumberFormatException e) {
System.out.println("Try again");
}
} while (!isPomoInterv);
boolean isBreakInterv = false;
do {
System.out.println("Please, Enter the break interval: ");
String temp = scanner.nextLine();
try {
if (Integer.parseInt(temp) > 0) {
breakInterv = Integer.parseInt(temp);
isBreakInterv = true;
}
} catch (NumberFormatException e) {
System.out.println("Try again");
}
} while (!isBreakInterv);
boolean isTerminalBreakInterv = false;
do {
System.out.println("Please, Enter the terminal break interval ");
String temp = scanner.nextLine();
try {
if (Integer.parseInt(temp) > 0) {
terminalBreakInterv = Integer.parseInt(temp);
isTerminalBreakInterv = true;
}
} catch (NumberFormatException e) {
System.out.println("Try again");
}
} while (!isTerminalBreakInterv);
System.out.println("Done!");
System.out.println(sessionName);
System.out.println(pomoInterv);
System.out.println(breakInterv);
System.out.println(terminalBreakInterv);
The comment on your question by scary-wombat is correct. i have used his comment to code the above.
I actually solved it, i just had to add a (scanner.next();) in the catch statement as below, it's because how the Scanner class works, see the code below,
import java.util.InputMismatchException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String sessionName;
int pomoInterv, breakInterv, terminalBreakInterv;
System.out.println("Please, Enter the session name: ");
sessionName = scanner.nextLine();
while (true) {
try {
System.out.println("Please, Enter the Pomodoro interval: ");
pomoInterv = scanner.nextInt();
break;
} catch (InputMismatchException ex) {
scanner.next();
System.out.println(ex.getMessage());
}
}
while (true) {
try {
System.out.println("Please, Enter the break interval: ");
breakInterv = scanner.nextInt();
break;
} catch (InputMismatchException ex) {
scanner.next();
System.out.println(ex.getMessage());
}
}
while (true){
try {
System.out.println("Please, Enter the terminal break interval ");
terminalBreakInterv = scanner.nextInt();
break;
} catch (InputMismatchException ex) {
scanner.next();
System.out.println(ex.getMessage());
}
}
System.out.println("Done!");
System.out.println(sessionName);
System.out.println(pomoInterv);
System.out.println(breakInterv);
System.out.println(terminalBreakInterv);
}
}
check this answer
https://stackoverflow.com/a/47852703/12565862
Because you don't have a break; in catch block. When there is exception, you print the message. But once it comes out of catch block, while loop still satisfies its condition and execute again. Try adding break; inside catch block too.
Im trying to catch an InputMismatchException it works at the first interraction , but when the menu() method is called again , it starts looping until it gets stuck in an error.
In the try catch my objective was to get an error message and after that start the menu() method again.
I have the following code:
public class Menu extends ProfilesManager {
static Scanner sc = new Scanner(System.in);
public static void menu() {
int number;
System.out.println("** Welcome... **\n ");
System.out.println("* what you wanna do?:\n");
System.out.println("(1) Login \n(2) Register \n(3) Find User \n(4) Exit\n");
System.out.print("-Answer?: ");
try {
number = sc.nextInt();
if (number == 1) {
Login();
} else if (number == 2) {
Register();
} else if (number == 3) {
FindUser();
} else if (number== 4) {
Exit();
}
} catch (InputMismatchException e) {
System.out.println("Error , only numbers!!");
menu();
}
}
}
}
This is because once you enter a wrong input. you are not clearing it and Scanner will keep on reading it and every time it will give you InputMisMatchException
You need to clear it in your catch block
}catch(InputMismatchException e){
System.out.println("Error , only numbers!!");
sc.nextLine();
// Put 2 second delay
try{
Thread.sleep(2000);
}catch(InterruptedException ex){
ex.printStackTrace();
}
menu();
}
You have infinite recursion. You gotta move menu() out of the catch block if you want to call it again. Otherwise it's infinite loop.
I guess you should write sc = new Scanner(System.in); after System.out.println("Error , only numbers!!");
This question already has answers here:
Error catching with try-catch and while loop [duplicate]
(1 answer)
How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
(5 answers)
Closed 7 years ago.
Hi I´m newbie in programming and I have this problem. I want to get input from user , using scanner. Program is supposed to try if input is valid, then call a function to do the job. Problem is I want program to repeat aking for input from user, if input is not valid. So I have try block in a while loop. The problem is on the first iteration of while loop everything is ok but when I insert invalid input and while loop is forced to iterate second time, try block is not executed and boolean which is condition of while loop is not set to false. So while loop runs for ever. Plz be kind.
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
boolean isRunning = true;
int input;
while(isRunning) {
System.out.println("insert a number:");
try {
input = scanner.nextInt();
inputToString(input);
isRunning = false;
} catch(InputMismatchException e) {
System.out.println("input musi byt cele cislo");
isRunning = true;
}
}
}
public static void inputToString(int input) {
System.out.println(input);
}
You need to consume invalid number from Scanner before asking for new one since nextInt didn't consume it, but thrown exception.
} catch (InputMismatchException e) {
System.out.println("input musi byt cele cislo");
scanner.next();//consume
isRunning = true;
}
But you should not use exceptions and try-catch sections as main part of control logic. Scanner provides hasNextInt() method to test if user provided valid input. So your code should be like
System.out.print("give me the money:");//ask user of integer
while(!scanner.hasNextInt()){//test is provided value is valid integer
String token = scanner.next();//consume incorrect value
//inform that value is not correct and ask for new one
System.our.println(token + " is not considered as valid number");
System.our.print("please try again:");
}
//here we know that user provided valid integer
value = scanner.nextInt();
The problem with your approach is that when the input is not a valid int you leave it in the input buffer. The next loop will see exactly the same input, and it would repeat exactly the same actions (throw, catch, continue with the loop).
What you should do is to drop the incorrect input from the scanner when you see that it does not match what you expect. You could do it in your catch block, like this:
try {
input = scanner.nextInt();
inputToString(input);
isRunning = false;
} catch(InputMismatchException e) {
System.out.println("input musi byt cele cislo");
isRunning = true;
scanner.nextLine(); // Drop input from the scanner's buffer
}
A better approach would be to not rely on try/catch in the scanning code at all. Scanner provides a convenient way for you to avoid exceptions: calling hasNextInt before you call nextInt lets you find out ahead of time if the exception would be thrown or not, and clean the wrong data from the buffer:
while(isRunning) {
System.out.println("insert a number:");
if (scanner.hasNextInt()) {
input = scanner.nextInt();
inputToString(input);
isRunning = false;
} else {
System.out.println("input musi byt cele cislo");
isRunning = true;
scanner.nextLine(); // Drop input from the scanner's buffer
}
}
you should reinitialize Scanner reference before scanning input
public static void main(String args[]) {
Scanner scanner = null;
boolean isRunning = true;
int input;
while (isRunning) {
System.out.println("insert a number:");
try {
scanner = new Scanner(System.in);
input = scanner.nextInt();
inputToString(input);
isRunning = false;
} catch (InputMismatchException e) {
System.out.println("input musi byt cele cislo");
isRunning = true;
}
}
}
public static void inputToString(int input) {
System.out.println(input);
}
this works
Requirement:
Accept 10 numbers, input them into an array and then invoke a method to calculate and return the smallest. This program is suppose to be error proof so when a user enters an invalid entry, it notifies the user and reprompts. I am trying to use try catch but when an invalid entry is entered, ie a character, the scanner won't reprompt.
Any ideas?
Tried:
//Variables
double [] doubleArray = new double[10];
Scanner input = new Scanner(System.in);
//Prompt
System.out.println("This program will prompt for 10 numbers and display the smallest of the group");
//Get values
for (int i = 0; i < doubleArray.length; i++) {
try {
System.out.println("Please enter entry "+ (i+1));
doubleArray[i] = input.nextDouble();
} catch (InputMismatchException e) {
// TODO: handle exception
System.out.println("Please enter a rational number");
i--;
}
}
//Invoke method and display result
System.out.println("The smallest value is: "+index(doubleArray));
I don't see any call to input.nextLine(), which means nothing is ever consuming the \n entered by the user. There's a good example on scanner.nextLine usage here. If you add a call to it in your catch block, you should be all set.
Try calling input.nextLine(); in your catch. Then the \n will be taken from the input which let's you enter the next new number.
for(int i = 0; i < doubleArray.length; ++i) {
try {
doubleArray[i] = input.nextDouble();
} catch(Exception e) {
input.nextLine();
--i;
}
}
Try something like (and make sure you consume the whole line unless you want to allow multiple numbers to be input on the same line
boolean validEntry = false;
System.out.println("Enter a rational number: ");
while (!validEnry) {
try {
double value = input.nextDouble();
validEntry = true;
doubleArray[i] = value;
} catch (Exception e) {
System.out.println("Entry invalid, please enter a rational number");
}
}
...
You have to discard the false inputted data, add input.nextLine() in the catch block.
I am using a while loop to make sure that the value entered to a scanner object is an integer as such:
while (!capacityCheck) {
try {
System.out.println("Capacity");
capacity = scan.nextInt();
capacityCheck = true;
} catch (InputMismatchException e) {
System.out.println("Capacity must be an integer");
}
}
however, if the user does not enter an integer, when it should go back and take another input it just repeatedly prints "Capacity" followed by the output in the catch without asking for more input. How do I stop this?
scan.nextLine();
Put this piece of code inside your catch block, to consume the non integer character along with the new line character which is stays in the buffer(hence, infinitely printing the catch sysout), in the case where you've given a wrong input.
Ofcourse, there are other cleaner ways to achieve what you want, but I guess that will require some refactoring in your code.
Use the following:
while (!capacityCheck) {
System.out.println("Capacity");
String input = scan.nextLine();
try {
capacity = Integer.parseInt(input );
capacityCheck = true;
} catch (NumberFormatException e) {
System.out.println("Capacity must be an integer");
}
}
Try this :
while (!capacityCheck) {
try {
System.out.println("Capacity");
capacity = scan.nextInt();
capacityCheck = true;
} catch (InputMismatchException e) {
System.out.println("Capacity must be an integer");
scan.nextLine();
}
}
Try putting this at the end of the loop -
scan.nextLine();
Or better to put it in the catch block.
while (!capacityCheck) {
try {
System.out.println("Capacity");
capacity = scan.nextInt();
capacityCheck = true;
} catch (InputMismatchException e) {
System.out.println("Capacity must be an integer");
scan.nextLine();
}
}
I see no need for a try/catch or capacityCheck as we have access to the method hasNextInt() - which checks if the next token is an int. For instance this should do what you want:
while (!scan.hasNextInt()) { //as long as the next is not a int - say you need to input an int and move forward to the next token.
System.out.println("Capacity must be an integer");
scan.next();
}
capacity = scan.nextInt(); //scan.hasNextInt() returned true in the while-clause so this will be valid.