Java - try/catch infinite repeat - java

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.

Related

Program loops when invalid character is entered [duplicate]

This question already has answers here:
How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
(5 answers)
Closed last month.
So I'm building a program which takes ints from user input. I have what seems to be a very straightforward try/catch block which, if the user doesn't enter an int, should repeat the block until they do. Here's the relevant part of the code:
import java.util.InputMismatchException;
import java.util.Scanner;
public class Except {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean bError = true;
int n1 = 0, n2 = 0, nQuotient = 0;
do {
try {
System.out.println("Enter first num: ");
n1 = input.nextInt();
System.out.println("Enter second num: ");
n2 = input.nextInt();
nQuotient = n1/n2;
bError = false;
}
catch (Exception e) {
System.out.println("Error!");
}
} while (bError);
System.out.printf("%d/%d = %d",n1,n2, nQuotient);
}
}
If I enter a 0 for the second integer, then the try/catch does exactly what it's supposed to and makes me put it in again. But, if I have an InputMismatchException like by entering 5.5 for one of the numbers, it just shows my error message in an infinite loop. Why is this happening, and what can I do about it? (By the way, I have tried explicitly typing InputMismatchException as the argument to catch, but it didn't fix the problem.
You need to call next(); when you get the error. Also it is advisable to use hasNextInt()
catch (Exception e) {
System.out.println("Error!");
input.next();// Move to next other wise exception
}
Before reading integer value you need to make sure scanner has one. And you will not need exception handling like that.
Scanner scanner = new Scanner(System.in);
int n1 = 0, n2 = 0;
boolean bError = true;
while (bError) {
if (scanner.hasNextInt())
n1 = scanner.nextInt();
else {
scanner.next();
continue;
}
if (scanner.hasNextInt())
n2 = scanner.nextInt();
else {
scanner.next();
continue;
}
bError = false;
}
System.out.println(n1);
System.out.println(n2);
Javadoc of 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.
YOu can also try the following
do {
try {
System.out.println("Enter first num: ");
n1 = Integer.parseInt(input.next());
System.out.println("Enter second num: ");
n2 = Integer.parseInt(input.next());
nQuotient = n1/n2;
bError = false;
}
catch (Exception e) {
System.out.println("Error!");
input.reset();
}
} while (bError);
another option is to define Scanner input = new Scanner(System.in); inside the try block, this will create a new object each time you need to re-enter the values.
To follow debobroto das's answer you can also put after
input.reset();
input.next();
I had the same problem and when I tried this. It completely fixed it.
As the bError = false statement is never reached in the try block, and the statement is struck to the input taken, it keeps printing the error in infinite loop.
Try using it this way by using hasNextInt()
catch (Exception e) {
System.out.println("Error!");
input.hasNextInt();
}
Or try using nextLine() coupled with Integer.parseInt() for taking input....
Scanner scan = new Scanner(System.in);
int num1 = Integer.parseInt(scan.nextLine());
int num2 = Integer.parseInt(scan.nextLine());
To complement the AmitD answer:
Just copy/pasted your program and had this output:
Error!
Enter first num:
.... infinite times ....
As you can see, the instruction:
n1 = input.nextInt();
Is continuously throwing the Exception when your double number is entered, and that's because your stream is not cleared. To fix it, follow the AmitD answer.
#Limp, your answer is right, just use .nextLine() while reading the input. Sample code:
do {
try {
System.out.println("Enter first num: ");
n1 = Integer.parseInt(input.nextLine());
System.out.println("Enter second num: ");
n2 = Integer.parseInt(input.nextLine());
nQuotient = n1 / n2;
bError = false;
} catch (Exception e) {
System.out.println("Error!");
}
} while (bError);
System.out.printf("%d/%d = %d", n1, n2, nQuotient);
Read the description of why this problem was caused in the link below. Look for the answer I posted for the detail in this thread.
Java Homework user input issue
Ok, I will briefly describe it. When you read input using nextInt(), you just read the number part but the ENDLINE character was still on the stream. That was the main cause. Now look at the code above, all I did is read the whole line and parse it , it still throws the exception and work the way you were expecting it to work. Rest of your code works fine.

Write a program that will give the use prompt to enter two doubles value

Professor requires us to write a program that will give the user prompt to enter two float (or double) values. If the values inputted are correct then display the inputted two values. If user enters characters instead of numbers or if they enter invalid numbers then the program will display the error message and ask the user to re-enter the correct values again. It only exits when the correct input is received and displayed.
However, I wrote a program that will only work if the user input the two right doubles. Can someone helps me to change the line about catching errors? Thanks.
import java.util.Scanner;
public class FiveSecond {
static void printMenu() {
System.out.println("Welcome to get two doubles program:");
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
boolean valid = false;
double first = 0;
double second = 0;
printMenu();
while(!valid) {
System.out.print("Enter two doubles, seperate by space ");
try {
first = Double.parseDouble(scan.next());
second = Double.parseDouble(scan.next());
} catch (NumberFormatException e) {
System.out.println("Try again");
}
valid = true;
}
System.out.println("You entered valid choice: " + first + " " +second);
System.out.println("Thank you for giving your choice.");
scan.close();
}
}
Try this:
catch (NumberFormatException e) {
System.out.println("Try again");
continue;
}
In addition to the previous comments, you have to be careful, because the scanner will 'remember' a previously correct double if you don't reset it :
EDITED: Thanks to #Stultuske comment
while (!valid) {
System.out.print("Enter two doubles, seperate by space ");
try {
first = Double.parseDouble(scan.next());
second = Double.parseDouble(scan.next());
valid = true;
}
catch (NumberFormatException e) {
System.out.println("Try again");
scan.nextLine(); // <------- Important line
}
}

INVALID INPUT AND LOOP

T student
Im wondering if the user input a Character not an integer.How can i Show the word INVALID to him
and let him Type again.
EXAMPLE:
input a two number
a
INVALID try Again:1
2
Sum of two number=3
public static void main(String[] args) {
int x = 0, y, z;
System.out.println("Enter two integers to calculate their sum");
Scanner in = new Scanner(System.in);
try {
x = in.nextInt();
} catch (InputMismatchException e ) {
System.out.print("INVALID");
}
y = in.nextInt();
z = x + y;
System.out.println("Sum of the integers = " + z);
}
You can do for example:
while(true) {
try {
x = in.nextInt();
break;
} catch (InputMismatchException e ) {
System.out.print("INVALID try again:");
in.next(); //To wait for next value otherwise infinite loop
}
}
Basically you need to add the input into a loop and keep looping until you get valid input. You can write it in different ways but that should be the idea.
The in.next() in the catch is required because nextInt() doesn't consume the new line character of the first input and this way we skip to that.
If I were you I would use in.nextLine() for each line of parameters and the manipulate the String that I get to check for valid input instead of waiting for exception.

I'm trying to loop for a positive integer, but I keep getting exceptions in the main method even though I'm using a try-catch

Here's my code:
public static double[] getArrayInput() {
Scanner stdin = new Scanner(System.in);
int arrayLength;
double[] arrayInput;
try {
System.out.print("Please enter the length of the array: ");
arrayLength = stdin.nextInt();
while (arrayLength <= 0) {
System.out.print("Invalid input, please enter a positive integer: ");
arrayLength = stdin.nextInt();
}
}
catch (InputMismatchException ex) {
System.out.print("Invalid input, please enter a positive integer: ");
arrayLength = stdin.nextInt();
}
arrayInput = new double[arrayLength];
System.out.print("Please enter the array elements: ");
for (int i = 0; i < arrayLength; i++) {
do {
double j = stdin.nextDouble();
arrayInput[i] = j;
} while (arrayInput.length < arrayLength);
}
return arrayInput;
}
I need to be able to continuously prompt for an integer value if a non-integer is entered. I read online that you can use the scanner.hasNextInt() method to do this, but every time I try to implement it, I keep getting new exceptions in my main method.
Should I expect for an exception to go to my main method if I have a catch block in this method?
I did notice the problem and is marked here in the complete program:
As you will notice you will need to do stdin.nextLine() to skip the last invalid input from being read again by the scanner.
Other than that, there is a bit of refactoring to your code.
public static double attemptInputElement(Scanner stdin) {
try {
double j = stdin.nextDouble();
} catch (InputMismatchException ex) {
System.out.print("Invalid input, please enter a valid element");
stdin.nextLine(); // skip the last input
attemptInputElement(stdin);
}
return 0.0; // should never get reached.
}
public static double[] getArrayInput() {
Scanner stdin = new Scanner(System.in);
int arrayLength;
double[] arrayInput = null;
System.out.print("Please enter the length of the array: ");
try {
arrayLength = stdin.nextInt();
while (arrayLength <= 0) {
System.out.print("Invalid input, please enter a positive integer: ");
arrayLength = stdin.nextInt();
}
} catch (InputMismatchException ex) {
System.out.print("Invalid input, please enter a positive integer: ");
stdin.nextLine(); // skip the last input
arrayLength = stdin.nextInt();
}
arrayInput = new double[arrayLength];
System.out.print("Please enter the array elements: ");
for (int i = 0; i < arrayLength; i++) {
do {
arrayInput[i] = attemptInputElement(stdin);
} while (arrayInput.length < arrayLength);
}
return arrayInput;
}
Add:
catch(Exception e)
{
//catch all exceptions here
}
That way it won't go to Main.
Next, it seems un-necessary to have two loops just to fill in the array elements. And you also probably want to have a try/catch around that nextDouble()

Scanner keeps skipping input whist using nextInt() and loops

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.

Categories

Resources