I just learned about the 'try' statement in Java, and what I'm trying to do is to have this input loop until the user's input is both an integer and a positive one.
This is my code so far:
int scanning () {
Scanner scan = new Scanner(System.in);
int input = 0;
boolean loop = false;
do {
try {
System.out.print("Amount: ");
input = scan.nextInt();
if (input < 0) {
System.out.println("Error. Invalid amount entered.");
loop = true;
}
} catch (Exception e) {
System.out.println("Error: Invalid input");
loop = true;
}
} while (loop);
return input;
}
However it goes through an infinite loop when the user inputs an invalid integer, printing the error message over and over. The expected outcome is to keep asking the user for a valid input.
This code will help you to be in infinite loop and also throw a exception when input is a -ve integer.
The exception handling in java is one of the powerful mechanism to handle the runtime errors so that normal flow of the application can be maintained.
Most of the times when we are developing an application in java, we often feel a need to create and throw our own exceptions.So first create a user defined exception AmountException.
public class AmountException extends Exception {
private static final long serialVersionUID = 1L;
public AmountException() {
// TODO Auto-generated constructor stub
System.out.println("Error. Invalid amount entered");
}
}
And now edit your scanning() to this :
int scanning () {
Scanner scan = new Scanner(System.in);
int input = 0;
boolean loop = false;
do {
try {
System.out.print("Amount: ");
input = scan.nextInt();
if (input < 0) {
loop = true;
throw new AmountException();
} else {
loop = false;
}
} catch (AmountException e) {
}
} while (loop);
return input;
}
Reset the value of loop variable in the do-while loop before each time just before checking the condition.
do {
try {
System.out.print("Amount: ");
input = scan.nextInt();
loop = false; // Reset the variable here.
if (input < 0) {
System.out.println("Error. Invalid amount entered.");
loop = true;
}
} catch (Exception e) {
System.out.println("Error: Invalid input");
scan.next(); // This is to consume the new line character from the previous wrong input.
loop = true;
}
} while (loop);
From you code, Change loop to false and when the valid input is given, it will terminate the while loop
boolean loop = false;
do {
try {
loop = false;
System.out.print("Amount: ");
input = scan.nextInt();
if (input < 0) {
System.out.println("Error. Invalid amount entered.");
loop = true;
}
} catch (Exception e) {
System.out.println("Error: Invalid input");
loop = true;
}
Add an else block after if, otherwise, loop will always stay true if the first input is invalid.
if (input < 0) {
System.out.println("Error. Invalid amount entered.");
loop = true;
} else {
loop = false;
}
Related
Just want to know if there was any better way of doing this since it's a lot of writing.
boolean isInputValid = false;
do {
System.out.print("Input: ");
final String input = sc.nextLine();
try {
age = Integer.parseInt(input);
} catch (NumberFormatException e) {
System.out.println("Invalid input. Try again");
continue;
}
if (input < 0 || 10 < input) {
System.out.println("Number outside of range.");
} else {
isInputValid = true;
}
} while (!isInputValid);
Well there are some things that can be ommited on a first look, but there is not much to remove.
Reduced integer parsing in a single line and removed input variable.
Change isInputValid to its negation isInputInvalid to remove else , Boolean assignment and negation in the while clause.
Moved if into the try clause to make redundant and remove the continue statement.
boolean isInputInvalid = true;
do {
System.out.print("Input: ");
try {
age = Integer.parseInt( sc.nextLine());
isInputInvalid = input < 0 || 10 < input;
if (isInputInvalid) {
System.out.println("Number outside of range.");
}
} catch (NumberFormatException e) {
System.out.println("Invalid input. Try again");
}
} while (isInputInvalid);
Well by first glance, I can see that you're comparing an incorrect variable type of string with an integer (your input variable), I'm just going to assume that you meant to compare the age. You should also put the if statements within your try/catch to ensure that its handled as intended (there's also no point in having it outside the try/catch if a NFE is thrown, it won't get ran anyways).
boolean isInputValid = true;
do {
System.out.print("Input: ");
final String input = sc.nextLine();
try {
age = Integer.parseInt(input);
if (age < 0 || 10 < age) {
System.out.println("Number outside of range.");
isInputValid = false;
}
} catch (NumberFormatException e) {
System.out.println("Invalid input. Try again");
continue;
}
} while (isInputValid);
Java beginner here. Im trying to create a do while loop where the user is supposed to key in some info. If the user keys in the correct info for something_A, the program should move on to asking user to key in info for something_B.
If the user enters incorrect info for this, the program should throw the respective exception which is InvalidExcep_B. I can get all this to work except once the exception is thrown, the program prompts the user to key in info from the beginning.
What should I do in order for the program to keep prompting only to input the piece of info that was incorrect?
boolean continueInput = true;
userInput = new Scanner (System.in);
System.out.println();
do {
try {
System.out.print("Enter Something_A: ");
something_A = userInput.nextInt();
if (condition ok) {
run statements;
}
System.out.print("Enter Something_B: ");
something_B = userInput.nextInt();
if (condition ok) {
run statements;
}
System.out.print("Enter Something_C: ");
something_C = userInput.nextInt();
if (condition ok) {
run statements;
}
continueInput = false;
}
catch (InvalidExcep_A e) {
System.out.println(e.toString());
continueInput = true;
}
catch (InvalidExcep_B e) {
System.out.println(e.toString());
continueInput = true;
}
catch (InvalidExcep_C e) {
System.out.println(e.toString());
continueInput = true;
}
} while (continueInput == true);
System.out.print("Enter Something_D: ");
something_D = userInput.next();
printInfo (parameters);
}
This is what I have so far. Thank you!
A couple things you could try.
Separating the do-while per input (right now, you have it all in one do-while). A bit repetitive but hey, it gets the job done.
Store a list of [input, actions] and just iterate through that in your while loop, the stop condition being once you finish that list.
You code is almost correct except since we need to remember whether Something_A is already finished or not. Similarly, for Something_B and Something_C we have to remember whether it is finished or not. So, the condition for Something_A, Something_B and Something_C should be different. Hence I chose conditionA, conditionB and conditionC for Something_A, Something_B and Something_C respectively.
The following code should solve your problem:
boolean continueInput = true;
boolean conditionA = true, conditionB = true, conditionC = true;
Scanner userInput = new Scanner (System.in);
System.out.println();
int somethingA = -1, somethingB = -1, somethingC = -1;
String somethingD = "";
do {
try {
if (conditionA) {
System.out.print("Enter Something_A: ");
somethingA = userInput.nextInt();
// runStatementsA();
conditionA = false; // Will not prompt for Something_A again.
}
if (conditionB) {
System.out.print("Enter Something_B: ");
somethingB = userInput.nextInt();
// runStatementsB();
conditionB = false; // Will not prompt for Something_B again.
}
if (conditionC) {
System.out.print("Enter Something_C: ");
somethingC = userInput.nextInt();
// runStatementsX();
conditionC = false; // Will not prompt for SOmething_C again.
}
continueInput = false;
} catch (java.util.InputMismatchException e) { // Replace 'java.util.InputMismatchException' with 'InvalidExcep_A'
System.out.println(e.toString());
userInput.next(); // Flush the scanner object
} catch (java.lang.NullPointerException e) { // Replace 'java.lang.NullPointerException' with 'InvalidExcep_B'
System.out.println(e.toString());
userInput.next(); // Flush the scanner object
} catch (java.lang.RuntimeException e) { // Replace 'java.lang.RuntimeException' with 'InvalidExcep_C'
System.out.println(e.toString());
userInput.next(); // Flush the scanner object
}
} while (continueInput == true);
System.out.print("Enter Something_D: ");
somethingD = userInput.next();
//printInfo(parameters);
I am trying to write a method that asks a user for a positive integer. If a positive integer is not inputted, a message will be outputted saying "Please enter a positive value". This part is not the issue. The issue is that when I try to implement a try catch statement that catches InputMismatchExceptions (in case user inputs a character or string by accident), the loop runs infinitely and spits out the error message associated with the InputMistmatchException.
Here is my code:
private static int nonNegativeInt(){
boolean properValue = false;
int variable = 0;
do {
try {
while (true) {
variable = scanner.nextInt();
if (variable < 0) {
System.out.println("Please enter a positive value");
} else if (variable >= 0) {
break;
}
}
properValue = true;
} catch (InputMismatchException e){
System.out.println("That is not a valid value.");
}
} while (properValue == false);
return variable;
}
Essentially what is happening is that the scanner runs into an error when the given token isn't valid so it can't advance past that value. When the next iteration starts back up again, scanner.nextInt() tries again to scan the next input value which is still the invalid one, since it never got past there.
What you want to do is add the line
scanner.next();
in your catch clause to basically say skip over that token.
Side note: Your method in general is unnecessarily long. You can shorten it into this.
private static int nonNegativeInt() {
int value = 0;
while (true) {
try {
if ((value = scanner.nextInt()) >= 0)
return value;
System.out.println("Please enter a positive number");
} catch (InputMismatchException e) {
System.out.println("That is not a valid value");
scanner.next();
}
}
}
you are catching the exception but you are not changing the value of variable proper value so the catch statement runs forever. Adding properValue = true; or even a break statement inside the catch statement gives you the required functionality!
I hope I helped!
You can declare the scanner at the start of the do-while-loop, so nextInt() will not throw an exception over and over.
private static int nonNegativeInt(){
boolean properValue = false;
int variable = 0;
do {
scanner = new Scanner(System.in);
try {
while (true) {
variable = scanner.nextInt();
if (variable < 0) {
System.out.println("Please enter a positive value");
} else if (variable >= 0) {
break;
}
}
properValue = true;
} catch (InputMismatchException e){
System.out.println("That is not a valid value.");
}
} while (properValue == false);
return variable;
}
This is indeed nearly identical to SO: Java Scanner exception handling
Two issues:
You need a scanner.next(); in your exception handler
... AND ...
You don't really need two loops. One loop will do just fine:
private static int nonNegativeInt(){
boolean properValue = false;
int variable = 0;
do {
try {
variable = scanner.nextInt();
if (variable < 0) {
System.out.println("Please enter a positive value");
continue;
} else if (variable >= 0) {
properValue = true;
}
} catch (InputMismatchException e){
System.out.println("That is not a valid value.");
scanner.next();
}
} while (properValue == false);
return variable;
}
Just add a break statement inside your catch.
Btw, you can get rid of the while loop by rewriting it like this:
try {
variable = scanner.nextInt();
if (variable < 0) {
System.out.println("Please enter a positive value");
} else {
properValue = true;
}
}
//...
This is a simple java function taking an input in double. It takes an input and first check if the value is non-numeric. And then check if the value is greater than 0 or not.
The problem I am facing is every time I enter a non-numeric input, it runs an infinite loop and only print "Enter a number greater or equal to 1.0: "
double getInput(double n) {
Scanner kbd = new Scanner(System.in);
boolean flag = false;
boolean check = false;
while (!flag) {
System.out.println("Enter a number greater or equal to 1.0: ");
try {
n = kbd.nextDouble();
if (n >= 0 || n < 0)
check = true;
} catch (InputMismatchException ex) {
err.print("Invalid Data Type (not Numeric)");
}
if (check == true) {
if (n < 0)
System.out.println("Invalid value (too small)");
else
flag = true;
}
}
return n;
}
kbd.nextDouble does not consume new line characters, hence these will be repeatedly passed into the while loop.
In your catch block instead of just throwing an exception, you can pass kbd.nextLine() so that for the next loop your input method is ready.
catch(InputMismatchException ex)
{
System.out.println("Invalid Data Type (not Numeric)");
kbd.nextLine();
}
Here is the complete code for you:
double getInput(double n)
{
Scanner kbd = new Scanner( System.in );
boolean flag =false;
boolean check = false;
while(!flag)
{
System.out.println("Enter a number greater or equal to 1.0: ");
try
{
n = kbd.nextDouble();
if(n>=0 || n<0)check = true;
}
**catch(InputMismatchException ex)
{
System.out.println("Invalid Data Type (not Numeric)");
kbd.nextLine();
}**
if(check==true)
{
if(n<0)
System.out.println("Invalid value (too small)");
else
flag = true;
}
}
return n;
}
Reading a double value from the scanner wont read the end of line
n = kbd.nextDouble();
so the scanner object will have something to read unless you get the line ending calling
kbd.nextLine();
the logic point to do this exactly after the exception comes...
catch (InputMismatchException ex) {
System.err.print("Invalid Data Type (not Numeric)");
kbd.nextLine(); ///here!!!
}
I'm sure this is something simple that I just can't spot, I have a do while loop prompting the user for an array size, which will be used for the rest of the program. If the user enters the right input, the program continues and works fine, but if the user enters the wrong input...
public static void main(String[] args)
{
// user enters up to 20 double values, stored in an array, user should enter 99999 to quit entering numbers. If user has not entered any numbers yet
// display an error message, otherwise, display each entered value and it's distance from the average
Scanner keyboard = new Scanner(System.in);
int arraySize = 0;
boolean isValid = false;
do
{
isValid = true;
arraySize = 0; // reset these values at start of each loop.
System.out.println("Enter an array size.");
try {
arraySize = keyboard.nextInt();
}
catch(NegativeArraySizeException mistake) {
System.out.println("Do not enter a negative number for the arrays size.");
System.out.println();
isValid = false;
}
catch(InputMismatchException mistake) {
System.out.println("Make sure to enter a valid number.");
System.out.println();
isValid = false;
}
} while (isValid == false);
If the user enters an invalid input, such as "red", the catch block kicks in and prints "Make sure to enter a valid number." and "Enter an array size." over and over without giving the user a chance to actually enter any input. I figured resetting the arraySize variable would fix it, but it doesn't. I guess the keyboard buffer has stuff in it, but no combination of empty printlns has worked so far.
I've heard that Exceptions shouldn't be used to validate user input. Why is that?
Regardless, it's not relevant to this question, as it is an exercise in Exception handling.
Without using isValid boolean variable and make simple code for input.
int arraySize = 0;
do {
System.out.println("Enter a valid array size.");
try {
arraySize = Integer.valueOf(keyboard.nextLine());
if (arraySize < 0) throw new NegativeArraySizeException();// for negative arry size
break;// loop break when got a valid input
} catch (Exception mistake) {
System.err.println("Invalid input: " + mistake);
}
} while (true);
You can add a keyboard.nextLine(); in the event of exception and it should resolve the issue.
try {
arraySize = keyboard.nextInt();
}
catch(NegativeArraySizeException mistake) {
System.out.println("Do not enter a negative number for the arrays size.");
System.out.println();
isValid = false;
keyboard.nextLine();
}
catch(Exception mistake) {
System.out.println("Make sure to enter a valid number.");
System.out.println();
isValid = false;
keyboard.nextLine();
}
Please see if this fix works for you. Scanner has a problem when you are trying to get the string from nextInt function. In this I have fetched the string and parsed to Integer and then handled the Number format exception
public static void main(String[] args) {
// user enters up to 20 double values, stored in an array, user should enter 99999 to quit entering numbers. If user has not entered any numbers yet
// display an error message, otherwise, display each entered value and it's distance from the average
Scanner keyboard = new Scanner(System.in);
int arraySize = 0;
boolean isValid = false;
do {
isValid = true;
arraySize = 0; // reset these values at start of each loop.
System.out.println("Enter an array size.");
try {
arraySize = Integer.parseInt(keyboard.next());
} catch (NegativeArraySizeException mistake) {
System.out.println("Do not enter a negative number for the arrays size.");
System.out.println();
isValid = false;
} catch (InputMismatchException mistake) {
System.out.println("Make sure to enter a valid number.");
System.out.println();
isValid = false;
} catch (NumberFormatException nfe) {
System.out.println("Make sure to enter a valid number.");
System.out.println();
isValid = false;
}
} while (isValid == false);
}
mmuzahid is almost there. But I added a way of checking negative number as well. Try this
Scanner keyboard = new Scanner(System.in);
int arraySize = 0;
boolean isValid = false;
do {
System.out.println("Enter a valid array size.");
try {
arraySize = Integer.valueOf(keyboard.nextLine());
if (arraySize < 0) {
System.out.println("Make sure to enter a valid positive number.");
} else {
break;
}
} catch (Exception mistake) {
System.out.println("Make sure to enter a valid number. Error:" + mistake);
}
} while (true);
Use keyboard.nextLine() and NumberFormatException
do {
// more code
try {
arraySize = Integer.valueOf((keyboard.nextLine()));
} catch (NegativeArraySizeException mistake) {
// more code
isValid = false;
} catch (InputMismatchException mistake) {
// more code
isValid = false;
} catch (NumberFormatException mistake) {
// more code
isValid = false;
}
} while (isValid == false);