Exception in do while loop - java

I have this piece of code:
do {
try {
input = sc.nextInt();
}
catch(Exception e) {
System.out.println("Wrong input");
sc.nextLine();
}
}
while (input < 1 || input > 4);
Right now, if I input 'abcd' instead of integer 1-4, it gives message "Wrong Input" and the program loops, how can I make it so that it also gives "Wrong Input" when I entered integer that doesn't fulfill the boolean (input < 1 || input >4)?
So that if I entered 5, it will also give me "Wrong Input".

Add this:
if(input < 1 || input > 4) {
System.out.println("Wrong input");
}
after input = sc.nextInt();

As of now, your try-catch block is checking if input is an int type. The do-while loop is checking input after it has been entered, so it is useless. The condition must be checked after the user enters what he/she wants. This should fix it:
do
{
try
{
input = sc.nextInt();
if(input < 1 || input > 4) // check condition here.
{
System.out.println("Wrong input");
}
}
catch(Exception e)
{
System.out.println("Expected input to be an int. Try again."); // tell user that input must be an integer.
sc.nextLine();
}
} while (input < 1 || input > 4);

You can also do this:
while (true) {
try {
input = sc.nextInt();
if (input >= 1 && input <= 4) {
break;
}
} catch (Exception e) {
System.out.println("Wrong input");
}
sc.nextLine();
}

Related

InputMismatchException in Java replacing while loop

In my task I need to put InputMismatchException when user tries to enter some values. User get some numbers from 1 to some number (simptoms.lenght).
int number=0;
do{
System.out.printf("Choose %d simptoms: \n", number+1);
for(int j=0; j< simptomi.length;j++){
System.out.printf("%d. %s %s\n", j + 1, simptoms[j].getName(),
simptoms[j].getValue());
}
System.out.print("Choose: ");
while(!scanner.hasNextInt()){
System.out.println("Please enter number!");
scanner.next();
}
number=scanner.nextInt();
scanner.nextLine();
if(number<0 || number> simptoms.length){
System.out.println("Error, choose again");
}
}while(number<0 || number> simptoms.length);
After this code I tried to do this:
instead of while(!scanner.hasNextInt()) I tried with try and I get this message:
Declaration, final or effectively final variable expected.
Is this the right way of replacing while loop or I should try to add something else.
I'm thinking about boolean = false and somehow try with that but I don't understand how to implement it properly.
I tried this:
try{
number=scanner.nextInt();
scanner.nextLine();
}
catch (InputMismatchException ex){
System.out.println("Please, enter number!");
}
Try it out! hope it helps!
try {
do {
number = scanner.nextInt();
if (!Character.isAlphabetic(number)) {
if (number > simptoms.length) {
System.out.println("Error, choose again");
System.out.println("Please enter number!");
}
}
} while (number != -1);
} catch (InputMismatchException e) {
System.out.println("Enter number");
}

NumberFormatException when checking if Integer is null

I am trying to make the user only enter a non-negative number and if the user closes the dialog the program should terminate.
Integer num = Integer.parseInt(JOptionPane.showInputDialog("Enter a positive number"));
if (num == null)
{
System.exit(0);
}
else if (num < 0)
{
num = Integer.parseInt(JOptionPane.showInputDialog("Enter a positive number"));
}
This code works if num is type String but not when I changed it to integer.
I get a NumberFormatException when I try to run it and the code in the if statment is dead code.
parseInt doesn't return null if passed a null/invalid string, it throws an exception, which you need to catch.
int num;
for (;;) {
String input = JOptionPane.showInputDialog("Enter a positive number");
if (input == null) System.exit(0);
try {
num = Integer.parseInt(input);
break;
} catch (NumberFormatException e) {
// continue;
}
}
The problem was that the function showInputDialog returns an empty string if exited or if the input was nothing so for fixing it you can check the input if it's empty look at this code:
num = (str.equals(""))?null:Integer.parseInt(str);
it's better to use a do{}while(); loop to get a more efficient code example:
String str;
Integer num;
do{
str = JOptionPane.showInputDialog("enter a positive number");
num = (str.equals(""))?null:Integer.parseInt(str);
if(num == null){
System.exit(0);
}
}while(num<0);
NFE - indicates that your string is not a number so you need to catch an error and make decision of what to do in case of unsuitable string, eg.
try {
if (Integer.parseInt("-123") < 0) {
// do job
}
} catch (NumberFormatException e) {
// string is not a number
// set value to default, log error, return error to users view
System.exit(9);
}

Endless loop with try and catch JAVA

so what I am trying to do is have the user input a valid coordinate in a matrix, that is an INT which is greater than -1,
Scanner scanner = new Scanner (System.in);
int coordinates[] = new int[2];
coordinates[0]=-1;
coordinates[1]=-1;
boolean check = true;
while (((coordinates[0]<0)||(coordinates[0]>R)) && check) {
System.out.print("Please enter a valid row number:\t");
try {
coordinates[0]=scanner.nextInt();
break;
}
catch (InputMismatchException e) {
}
}
while (((coordinates[1]<0)||(coordinates[1]>C)) && check) {
System.out.print("Please enter a valid col number:\t");
try {
coordinates[1]=scanner.nextInt();
break;
}
catch (InputMismatchException e) {
}
}
the problem is that it loops endlessly after entering a not valid input
int R is the size of the row
int C is the size of the collumn
Your problem is that you're not handling the error you're catching.
If you'll provide wrong format of number for the nextInt() method, then the InputMismatchException will be thrown. Then because the catch does nothing, the loop will continue (start from begining) and the scanner will read the same incorrect value, and so on...
So instead of this:
catch (InputMismatchException e) {
}
Try this:
catch (InputMismatchException e) {
System.out.println("Wrong number entered.");
scanner.nextLine();
}
This way you'll force scanner to move past the last incorrect input.
EDIT:
You're loop is also broken because you do break after reading the input. In that case if you'll put the negative number you'll break as well and won't check the loop condition. Remove the break statement and it will work as expected:
while (((coordinates[0]<0)||(coordinates[0]>R)) && check) {
System.out.print("Please enter a valid row number:\t");
try {
coordinates[0]=scanner.nextInt();
}
catch (InputMismatchException e) {
System.out.println("That's not a valid number.");
scanner.nextLine();
}
}
EDIT2:
public static void main(final String args[])
{
int maxRowsNumber = 10;
int maxColsNumber = 10;
Scanner scanner = new Scanner (System.in);
int coordinates[] = new int[2];
coordinates[0]=-1;
coordinates[1]=-1;
boolean check = true;
while (((coordinates[0]<0)||(coordinates[0]>maxRowsNumber)) && check) {
System.out.print("Please enter a valid row number:\t");
try {
coordinates[0]=scanner.nextInt();
}
catch (InputMismatchException e) {
System.out.println("That's not a valid number.");
scanner.nextLine();
}
}
while (((coordinates[1]<0)||(coordinates[1]>maxColsNumber)) && check) {
System.out.print("Please enter a valid col number:\t");
try {
coordinates[1]=scanner.nextInt();
}
catch (InputMismatchException e) {
System.out.println("That's not a valid number.");
scanner.nextLine();
}
}
System.out.println("Inserted RowsNumber: " + coordinates[0]);
System.out.println("Inserted RowsNumber: " + coordinates[1]);
}
Output:
Please enter a valid row number: 11
Please enter a valid row number: 22
Please enter a valid row number: 10
Please enter a valid col number: 11
Please enter a valid col number: 2
Inserted RowsNumber: 10
Inserted RowsNumber: 2
If by "not valid input" you mean "not any kind of integer", then your scanner will fail each time it tries to read another integer, so you'll hit your catch, and do nothing to stop the loop. Maybe you intended to set check to false in such circumstances? Or maybe you meant to put the break in each catch?
Using a break when a valid integer is read isn't right, because it might be a negative integer, which your loop guard says you don't want.
This is basically the same as what your doing, I just tried to improve it a little bit by removing hardcoded values, made variables more descriptive, and included input validations.
final int ROW = 0;
final int COL = 1;
int coordinates[] = new int[2];
coordinates[ROW] = -1;
coordinates[COL] = -1;
boolean isInputValid = true;
Scanner scanner = new Scanner(System.in);
do {
try {
System.out.print("Please enter a valid row number:\t");
coordinates[ROW] = Integer.parseInt(scanner.nextLine());
} catch (NumberFormatException nfe) {
isInputValid = false; //if the input is not int
}
} while (!isInputValid && (coordinates[ROW] < 0) //do this until the input is an int
|| (coordinates[ROW] > R)); //and it's also not less than 0 or greater than R
//same logic applies here
do {
try {
System.out.print("Please enter a valid col number:\t");
coordinates[COL] = Integer.parseInt(scanner.nextLine());
} catch (NumberFormatException nfe) {
isInputValid = false;
}
} while (!isInputValid && (coordinates[COL] < 0)
|| (coordinates[COL] > C));
Hope this helps.

Resume loop after caught exception

I am catching an inputMismatchException in my main method and want my do-while loop to iterate again after the exception is caught. I even coded an explicit continue statement but that didn't work. How can I do so?
public class AddressBookApp {
public static void main(String[] args) {
AddressBook abook = new AddressBook();
System.out.println("Welcome to the Address Book Application\n");
Scanner sc = new Scanner(System.in);
int menuNumber = 4;
loop:
do {
abook.menu();
try{
menuNumber = sc.nextInt();
System.out.println();
if (menuNumber < 1 || menuNumber > 4){
System.out.println("Please enter a valid menu number\n");
} else if (menuNumber == 1) {
abook.printEntries();
} else if (menuNumber == 2) {
abook.addEntry();
} else if (menuNumber == 3) {
abook.removeEntry();
} else {
System.out.println("Thanks! Goodbye.");
sc.close();
return;
}
} catch (InputMismatchException ime) {
System.out.println("Please enter an integer");
sc.next();
continue loop;
}
} while (menuNumber != 4);
sc.close();
}
}
You left menuNumber equal to 4, which is the termination condition of your loop. Of course your loop will end.
You initialized menuNumber to 4, but do not change it in case of an exception. The loop does attempt to continue, but exits because the statement menuNumber != 4 is false.
int menuNumber = 4;
loop:
do {
abook.menu();
try{
menuNumber = sc.nextInt();
System.out.println();
if (menuNumber < 1 || menuNumber > 4){
System.out.println("Please enter a valid menu number\n");
} else if (menuNumber == 1) {
abook.printEntries();
} else if (menuNumber == 2) {
abook.addEntry();
} else if (menuNumber == 3) {
abook.removeEntry();
} else {
System.out.println("Thanks! Goodbye.");
sc.close();
return;
}
} catch (InputMismatchException ime) {
System.out.println("Please enter an integer");
sc.next();
continue loop;
}
} while (menuNumber != 4);
Try this
} catch (InputMismatchException ime) {
if (fatal(ime)) {
throw ime;
} else {
// try again
continue;
}
The loop doesn't continue because an exception of a type OTHER than InputMistmatchException is being thrown. Change the catch to:
catch (Exception e)
or at least add that all encompassing catch condition.
A better solution is to inspect exactly what exception is being thrown and why, and then fix the problem leading to the exception. Having an all encompassing catch with a continue statement could, in theory, lead to an infinite loop because menuNumber is not incremented.

Taking keyboard input and running checks on it

I have the following method
public static int modeChooser(){
int choice = 0;
Scanner kb = new Scanner(System.in);
while(choice == 0){
try {
choice = kb.nextInt();
} catch (Exception e) {
continue;
}
if(choice < 1 || choice > 5){
continue;
}
}
return choice;
}
The goal is to only allow the user to put in 1,2,3,4, or 5;
If the user types a string or a too high/low number, the method should just restart until i have the proper int.
Here is an example for the flow:
User types: 1 -> all ok
User types: saddj -> method restarts -> user types 3 --> all ok
Any ideas?
Change to:
do {
// read choice value
if (choice < 1 || choice > 5) {
// hint to user
}
} while(choice < 1 || choice > 5);
I think you can simply put your check in the while condition itself as below:
while(choice < 1 || choice > 5){
try {
choice = kb.nextInt();
} catch (Exception e) {
//ignore the exception and continue
}
}
This way actually works fine:
public static int modeChooser(){
int choice = 0;
Scanner kb = new Scanner(System.in);
while(choice == 0){
try {
choice = kb.nextInt();
} catch (Exception e) {
System.out.println("Sorry but you have to enter 1,2,3,4, or 5! Please try again.");
choice = modeChooser();
}
}
if(choice < 1 || choice > 5){
System.out.println("Sorry but you have to enter 1,2,3,4, or 5! Please try again.");
choice = modeChooser();
}
return choice;
}
if(choice >= 1 && choice <= 5)
break;
else
choice = 0;
If kb.NextInt() fails the data in the input stream remains, you need to skip past it. If you don't skip the invalid data the loop will continuously try, and fail, to read the invalid input resulting in an infinite loop.
You can use kb.next() to skip over the invalid input:
while (true)
{
try
{
choice = kb.nextInt();
if(choice >= 1 && choice <= 5) break;
}
catch (InputMismatchException e)
{
e.printStackTrace();
kb.next();
}
}
I think it's better to use the Scanner.nextLine() and Integer.parseInt() methods:
while(choice < 1 || choice > 5){
try {
choice = Integer.parseInt(kb.nextLine());
} catch (Exception e) {
//...print error msg
}
}
You could include your condition on choice directly in the while condition:
while(choice < 1 || choice > 5){
try {
choice = kb.nextInt();
} catch (Exception e) {
continue;
}
}
(In your current code, is the user enters 7, choice takes that value, the while condition becomes false and your method returns 7, which it should not).
And instead of catching an exception, you could use the hasNextInt() method to make the code cleaner:
public static int modeChooser() {
int choice = 0;
Scanner kb = new Scanner(System.in);
while (choice < 1 || choice > 5) {
if (!kb.hasNextInt()) {
kb.next();
} else {
choice = kb.nextInt();
}
}
return choice;
}
If you do want to use a recursive method, it could look like:
public static int modeChooser() {
Scanner kb = new Scanner(System.in);
while (!kb.hasNextInt()) {
kb.next();
}
int choice = kb.nextInt();
return (choice >= 1 && choice <= 5) ? choice : modeChooser();
}

Categories

Resources