Try-Catch inside While Loop - java

The code below asks the user how many racers he/she would like.
while (true) { // loops forever until break
try { // checks code for exceptions
System.out.println("How many racers should" + " participate in the race?");
amountRacers = in.nextInt();
break; // if no exceptions breaks out of loop
}
catch (InputMismatchException e) { // if an exception appears prints message below
System.err.println("Please enter a number! " + e.getMessage());
continue; // continues to loop if exception is found
}
}
If a number is entered at amoutnRacers = in.nextInt(); the code breaks out of the loop and the rest of the program runs fine; however, when I enter something such as "awredsf" it should catch that exception, which it does. Instead of prompting the user again it loops continuously, which to me does not make sense.
The program prints like this when looping continuously:
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?Please enter a number! null
Please enter a number! null
Please enter a number! null
Please enter a number! null
Please enter a number! null
Please enter a number! null
Please enter a number! null
...
I do not understand what is going on amountRacers = in.nextInt(); so why is the user not able to enter a number?

Just add input.next() once you catch InputMismatchException.
catch (InputMismatchException e) { //if an exception appears prints message below
System.err.println("Please enter a number! " + e.getMessage());
input.next(); // clear scanner wrong input
continue; // continues to loop if exception is found
}
You need to clear the wrong input, which scanner automatically does not.

Today i solved this problem :-) This is my code. I think that i help
public int choice () throws Exception{
Scanner read = new Scanner(System.in));
System.out.println("Choose the option from the upper list");
int auxiliaryChoiceMenu = 5;
int auxiliaryVariable = -1;
boolean auxiliaryBoolean = false;
while (!auxiliaryBoolean) {
try {
auxiliaryVariable = read.nextInt();
read.nextLine();
} catch (Exception e) {
System.out.println("incorrect data, try again"+e);
read.nextLine();
continue;
}
if (auxiliaryVariable<0 || auxiliaryVariable>auxiliaryChoiceMenu){
System.out.println("incorrect data, try again");
} else {
auxiliaryBoolean = true;
}
choiceMenu = auxiliaryVariable;
}
return choiceMenu;
//choicemenu is a external variable
}

You may need to create a Scanner class for getting standard input streamed from the keyboard. You should have a statement somewhere in your code that creates an instance of a Scanner class like: Scanner in = new Scanner(System.in);
so the " in " variable in your statement: amountRacers = in.nextInt(); waits and scans for entered input from the keyboard and stores it.

Why use a loop with a try and catch?
My advice would be to always use a try and catch with either a while or do while loop, so you can ask the user to repeat his/her input. It also depends which loop you already use and/or on how your code is structured.
For example if you already have a do while loop then I would advice you to simply adjust/modify your existing loop.
I will post some examples on how you can use a try and catch with a loop to repeat the input after a user has provided a wrong one.
See examples below:
Example 1
Scanner input = new Scanner(System.in);
int exampleInput = 0;
do {
try {
System.out.print("\nEnter an integer from 1 to 25: ");
exampleInput = input.nextInt();
}
catch (InputMismatchException e) { //if an exception appears prints message below
System.err.println("Wrong input! Enter an integer from 1 to 25");
input.next(); // Clear scanner buffer of wrong input
}
} while (exampleInput < 1 || exampleInput > 25);
System.out.println("Print exampleInput: " + exampleInput);
Example 2
Scanner input = new Scanner(System.in);
int exampleInput; // Here you don't need to initialize this variable because you don't need it as a condition for the loop.
boolean isDone = false;
do {
try {
System.out.print("\nEnter an integer: ");
exampleInput = input.nextInt();
isDone = true;
}
catch (InputMismatchException e) { //if an exception appears prints message below
System.err.println("Wrong input! Enter an integer");
input.next(); // Clear scanner buffer of wrong input
}
} while (!isDone);
System.out.println("Print exampleInput: " + exampleInput);
Example 3
Scanner input = new Scanner(System.in);
int exampleInput; // Here you don't need to initialize this variable because you don't need it as a condition for the loop.
boolean isDoneLoop2 = false;
while (!isDoneLoop2) {
try {
System.out.print("\nEnter an integer: ");
exampleInput = input.nextInt();
isDoneLoop2 = true;
}
catch (InputMismatchException e) { //if an exception appears prints message below
System.err.println("Wrong input! Enter an integer");
input.next(); // Clear scanner buffer of wrong input
}
}
System.out.println("Print exampleInput: " + exampleInput);

This works for me.
while (true) {
try {
System.out.print("Ingrese la cantidad de puestos de atenciĆ³n: ");
int puestos = Integer.parseInt(scn.nextLine());
break;
}
catch (NumberFormatException e) {
System.out.println("Ingrese un valor correcto");
scn.reset();
continue;
}
}

Related

Implementing try-catch inside a loop

I want to create a try-catch block inside a loop to give the user multiple opportunities to enter the info with the correct format. When I enter something with incorrect format, the program displays the sysout message "Please enter name and age with correct format." from the catch block.
The problem is when I enter the info with the correct formatting after this message, it keeps displaying the same message "Please enter name and age with correct format." even though it should exit and ask if I want to continue.
Here's what I have:
int inAge;
String inName;
while (true) {
try {
inAge = Integer.parseInt((input.substring((input.indexOf(',') + 1))));
inName = input.substring(0, input.indexOf(','));
list.add(new Plant(inName, inAge));
break;
} catch (Exception e) {
System.out.println("Please enter name and age with correct format.");
in.next();
}
}
System.out.println("Do you wish to continue? (Yes or No)");
endOrNo = in.nextLine();
if ("yes".equalsIgnoreCase(endOrNo))
go = true;
else
go = false;
possible that you call next() instead of nextLine(), that may read wrong input and keep taking you back to the exception block.
You need to update the value of input variable as so.
while (true) {
try {
input = in.nextLine(); // accept input
inAge = Integer.parseInt((input.substring((input.indexOf(',') + 1))));
inName = input.substring(0, input.indexOf(','));
list.add(new Plant(inName, inAge));
break;
} catch (Exception e) {
System.out.println("Please enter name and age with correct format.");
input = in.next();
}
}
System.out.println("Do you wish to continue? (Yes or No)");
endOrNo = in.nextLine();
if ("yes".equalsIgnoreCase(endOrNo))
go = true;
else
go = false;

Why does my try-catch when used to catch an error print out the error and my catch block?

I am currently learning about try-catch blocks of code and I am writing a piece of code that takes an input from a user and checks if its a integer or not. my code is
int classSize = 0;
boolean error = false;
do {
try{
System.out.println("Hello! Please enter how many Students you have in your class: ");
classSize = in.nextInt();
error = false;
}
catch(InputMismatchException e){
System.out.println("Invalid input. please make sure you enter numbers ONLY! No symbols or letters.");
classSize = in.nextInt();
error = true;
}
}while(error);
When I try to test it by entering letters I get both the error message and the try block message.
Hello! Please enter how many Students you have in your class:
asdfsda
Invalid input. please make sure you enter numbers ONLY! No symbols or
letters.
Exception in thread "main" java.util.InputMismatchException
at java.base/java.util.Scanner.throwFor(Scanner.java:939)
at java.base/java.util.Scanner.next(Scanner.java:1594)
at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
at ExcerciseOne.main(ExcerciseOne.java:65)
Why is it showing the catch block and the error message? Am I using the try-catch block properly?
You are catching the exception thrown in the try clause, but you are then reading from the scanner inside the catch again and thus throwing another exception, this time uncaught.
classSize = in.nextInt();
exists in both clauses, throwing an exception both times, but only gets caught when thrown from inside the try clause.
The in.nextInt() invocation inside the catch block reads the bad stream left behind by the first invocation of in.nextInt() in the try block.
What you can do is to remove the .nextInt() calls in the catch block:
boolean hasError = true;
while (hasError) {
try {
System.out.println("Hello! Please enter how many Students you have in your class: ");
classSize = in.nextInt();
hasError = false;
} catch (InputMismatchException e) {
System.out.println("Invalid input. please make sure you enter numbers ONLY! No symbols or letters.");
// variable has error remains true
}
}
Or better:
Since InputMismatchException is a subclass of RuntimeException, the kind of error that throws this error can be filtered out by if statements. Since you only need a proper integer as an input, you can validate the input using a regular expression.
boolean hasError = true;
String integerRegex = "[\\d]+"; // it means 1-to-many digits
while (hasError) {
System.out.println("Hello! Please enter how many Students you have in your class: ");
String input = in.nextLine();
if (input.matches(integerRegex)) {
classSize = Integer.parseInt(input);
hasError = false;
} else {
System.out.println("Invalid input. please make sure you enter numbers ONLY! No symbols or letters.");
// variable hasError remains true
}
}
Gendarme's answer is clear, and I add a correct demo for you:
public static void main(String[] args) {
int studentsCount = 0;
boolean hasError;
do {
try {
System.out.println("Hello! Please enter how many Students you have in your class: ");
Scanner in = new Scanner(System.in);
studentsCount = in.nextInt();
hasError = false;
} catch (InputMismatchException e) {
System.out.println("--> Invalid input. please make sure you enter numbers ONLY! No symbols or letters.");
hasError = true;
}
} while (hasError);
System.out.println("There are " + studentsCount + " students in your class.");
}

Scaner nextInt() - Shall I handle the InputMismatchException thrown by this method when user enters something other than integer?

While using the nextInt() method of Scanner class, if InputMismatchException is being thrown, shall I handle that by catch block ?
It's a runtime exception, but caused by user input and not programmer's mistake.
Here is my code.
package com.sample.programs;
import java.util.InputMismatchException;
import java.util.Scanner;
public class ScannerPractice {
public static void main(String[] args) {
readInteger();
}
private static void readInteger() {
// Created a Scanner object
Scanner input = new Scanner(System.in);
// Display a prompt text
System.out.println("Please enter an integer");
// Accept the input from user
int number;
try {
number = input.nextInt();
// Display the output to user
System.out.println("You entered: " + number);
} catch (InputMismatchException exception) {
System.err.println("You have entered wrong input. Please enter a number");
// Log the stack trace
readInteger();
} finally {
input.close();
}
}
}
Yes. Is better to handle the user wrong input beacouse you cannot control or be sure that the user will aligned data correctly, and you cannot read doubles, or strings with readInteger().
So I will handle the exception.
Regards.
No, you should call hasNextInt() before calling nextInt().
The exception truly means programmer error, since the programmer forgot to check validity before calling the method.
If you then want to prompt the user again, remember to discard the bad input first.
Scanner input = new Scanner(System.in);
int value;
for (;;) {
System.out.println("Enter number between 1 and 10:");
if (! input.hasNextInt()) {
System.out.println("** Not a number");
input.nextLine(); // discard bad input
continue; // prompt again
}
value = input.nextInt();
if (value < 1 || value > 10) {
System.out.println("** Number must be between 1 and 10");
input.nextLine(); // discard any bad input following number
continue; // prompt again
}
if (! input.nextLine().trim().isEmpty()) {
System.out.println("** Bad input found after number");
continue; // prompt again
}
break; // we got good value
}
// use value here
// don't close input

WHILE Loop Condition Does Not Validate Input

I have a WHILEloop which checks for marks for a particular student. However, it does not loop if the value is invalid (input less than 0 and more than 100):
int marks= -1;
System.out.print("Student Marks (/100): ");
while (((marks< 0) || (marks> 100))) {
try {
marks = Integer.parseInt(sc.nextLine());
break;
} catch (NumberFormatException nfe) {
System.err.println("Error: Invalid Mark(s)");
System.out.print("Student Marks (/100): ");
}
}
It does catches exception if characters other than numbers are entered.
But it does not loop again if value if less than 0 or more than 100.
I have tried making many changes to it but to no result.
Any help given is appreciated!
You should remove the break statement, since it breaks you out of the loop regardless of what value of marks was input.
Always use continue instead of break if you want to keep the loop running.
You may check the marks inside the while loop with an if condition and here you may use break -
import java.util.Scanner;
public class TakeInput{
public static void main(String args[]){
int marks= -1;
Scanner sc = new Scanner(System.in);
System.out.print("Student Marks (/100): ");
while (sc.hasNext()) {
try {
marks = Integer.parseInt(sc.nextLine());
if(marks<0 || marks>100){
break;
}
//do something
// with the marks
//take new marks
System.out.print("Student Marks (/100): ");
} catch (NumberFormatException nfe) {
System.err.println("Error: Invalid Mark(s)");
System.out.print("Student Marks (/100): ");
}
}
}
}
Now as long as you enter anything except a number n when n<0 || n>100 will continue the loop. Any NumberFormatExeption take you to the catch block.
If you enter 34 then it goes to the while block and prompt for a next number.
Then if you enter 56 then it dose the same thing.
When you enter any String rather than a number than it goes to the catch block
This process continues until you enter a invalid number (n>100 || n<100). Pressing Ctrl+C also exit you from the loop.
Hope it will help you.
Thanks a lot.

While loop executing once before prompt

This was a difficult question to research, so please forgive me if this is a duplicate.
Basically, I have a while loop that'll only break if a code the user scans is an integer. I check this by trying Integer.parseInt(integer) and only breaks the loop if a NumberFormatException isn't thrown.
My problem, is that when the loop executes for the first time, the exception is thrown, without any user input.
Here's my code:
Scanner input = new Scanner(System.in);
while (true)
{
System.out.print("Please scan barcode: ");
int inCode = 0;
try
{
inCode = Integer.parseInt(input.next());
}
catch (NumberFormatException e)
{
System.out.println("Numbers only, please.");
}
if (inCode != 0) {
// Do Stuff
} else {
System.out.println("Code can't be zero!");
}
}
What should happen, is this:
Please scan barcode: // And here they enter the barcode
But instead this happens:
Please scan barcode: Numbers only, please.
Please scan barcode:
EDIT:
As per Bohemian's answer, I added the continue keyword to my code. That solves the issue, but only halfway. As per the request of the people who put my question on hold (With good reason, as I now see) I'll post a SSCCE for you guys. I'm going to remove the methods for interfacing with the database, though, only keeping the path that has the problem: creating a new account based on the code.
Scanner input = new Scanner(System.in);
while (true)
{
System.out.print("Please scan barcode: ");
int inCode = 0;
try
{
inCode = Integer.parseInt(input.next());
}
catch (NumberFormatException e)
{
System.out.println("Numbers only, please.");
continue;
}
if (true) // Here it checks if an account associated with the code entered exists in the database. Because I'm having issues when it creates a new account, I've made this true.
{
System.out.println("No account associated with that code! Create one?");
System.out.print("(yes/no): ");
String answer = input.next();
if (answer.equalsIgnoreCase("yes"))
{
System.out.println("Alright.");
System.out.print("Please enter a name: ");
String name = input.next();
System.out.print("Alright. Now I'll add that to the database... ");
// Here I add that to the database. Omitted.
System.out.println("Done! Please scan again to interface.");
}
else if (answer.equalsIgnoreCase("no"))
{
System.out.println("Okay then.");
}
else
{
System.out.println("Defaulting to no.");
}
}
}
// I still haven't written the code to interface with the account.
What happens now is, it says (in the first iteration)
Please scan barcode:
But, after going through the process of adding the account, it loops again and says:
Please scan barcode: Numbers only, please.
Please scan barcode:
EDIT:
Please note, everything is inside a while loop, so that when everything that the user has done is finished, it'll return to:
Please scan barcode:
I think what you want is this:
Scanner input = new Scanner(System.in);
while (true) {
System.out.print("Please scan barcode: ");
int inCode = 0;
try {
inCode = Integer.parseInt(input.next());
if (inCode != 0) {
// Do Stuff
break;
}
} catch (NumberFormatException e) {
System.out.println("Numbers only, please.");
}
}
The code you have could be structured better, which would both make it clearer what is happening and easier to track down problems. You only want to loop on the data input - so just loop on the data input:
int inCode = 0;
while (true) {
System.out.print("Please scan barcode: ");
try {
inCode = Integer.parseInt(input.next());
break;
} catch (NumberFormatException e) {
System.out.println("Numbers only, please.");
}
}
// Do stuff
You should consider using scanner.hasNextInt() and scanner.nextInt() rather than scanner.next() though. This will also avoid the need for using the exception like this. Normally using Exceptions to control program flow is a bad idea - really they should be used for handling exceptional circumstances. Integer.parseInt doesn't give you any alternatives, but scanner does.
After the edits, it's clear what the problem is: your while (true) loop doesn't have a break statement in it, so it will keep looping forever.
Personally, I'd suggest moving most of your code out of the loop, and only keeping the barcode-parsing code in it, e.g. like this:
int inCode;
while (true) {
System.out.print("Please scan barcode: ");
try {
inCode = Integer.parseInt(input.next());
if (inCode == 0) {
System.out.println("Code can't be zero!");
} else {
break; // we got a valid barcode! end the loop and move on...
}
} catch (NumberFormatException e) {
System.out.println("Numbers only, please.");
// no need for a "continue" here, since the loop will restart anyway
}
}
// rest of the code here...
or possibly even:
int inCode;
while (true) {
System.out.print("Please scan barcode: ");
try {
inCode = Integer.parseInt(input.next());
} catch (NumberFormatException e) {
System.out.println("Numbers only, please.");
continue;
}
if (inCode == 0) {
System.out.println("Code can't be zero!");
continue;
}
break; // we have a valid barcode! end the loop and move on...
}
// rest of the code here...
I would just continue the loop if there's bad input, then you don't need to test it later:
while (true) {
System.out.print("Please scan barcode: ");
int inCode = 0;
try {
inCode = Integer.parseInt(input.next());
} catch (NumberFormatException e) {
System.out.println("Numbers only, please.");
continue; // ADDED THIS LINE
}
// Do Stuff with inCode
}
Note that by your code testing for zero after the input, you preclude zero as valid input. This code allows any number, including zero. Small point, but there's no worries about edge cases.
You can try this
String in=null;
while (true) {
System.out.print("Please scan barcode: ");
int inCode = 0;
try {
in= input.next();
inCode=Integer.parseInt(in);
} catch (NumberFormatException e) {
System.out.println("Numbers only, please.");
}
if (inCode != 0) {
// Do Stuff
} else {
// Repeat loop
}
or you can directly read an integer through Scanner object instead of using Integer.parseInt() method.
int inCode=0;
while(true) {
System.out.print("Please scan barcode : ");
inCode=input.nextInt();
if(inCode!=0){ //do stuff }
else { //Repeat Loop }
}

Categories