I wrote method that checks if a given String input can be parsed as positive integer or not.
Is there a cleaner way to write this so I'm not repeating the code that rejects the value?
try {
int num = Integer.parseInt(value);
if (num <= 0) {
errors.rejectValue(FIELD_FILE, INVALID_MESSAGE_KEY, new Object[]{lineNumber, fieldName}, "Line {0}: {1} must be a positive integer");
}
} catch (NumberFormatException e) {
errors.rejectValue(FIELD_FILE, INVALID_MESSAGE_KEY, new Object[]{lineNumber, fieldName}, "Line {0}: {1} must be a positive integer");
}
I belive this is the cleaner you can get.
Even if it passes on the try if it is not in the range of results that you expect you force it into the catch.
try {
int num = Integer.parseInt(value);
if (num <= 0) {
throw new NumberFormatException();
}
} catch (NumberFormatException e) {
errors.rejectValue(FIELD_FILE, INVALID_MESSAGE_KEY, new Object[]{lineNumber, fieldName}, "Line {0}: {1} must be a positive integer");
}
One simple way:
int num = 0;
try {
num = Integer.parseInt(value);
} catch (NumberFormatException e) {
num = -1;
}
if (num <= 0) {
errors.rejectValue(FIELD_FILE, INVALID_MESSAGE_KEY, new Object[]{lineNumber, fieldName}, "Line {0}: {1} must be a positive integer");
}
Related
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;
}
}
//...
I have an InputMismatchException which stops a decimal from being entered, but it doesn't help for negative integers/negative decimals.
if(userInput == 1) {
int l;
l = 0;
try {
l = input.nextInt();
} catch (InputMismatchException e) {
System.out.println("");
input.next();
}
}
If I add a do while loop with an if statement for anything equal to or less than zero it will loop within the if(userInput == 1) statement instead of starting from the beginning of the menu like it does if a positive decimal is entered. It also doesn't help for negative decimals.
I've tried to add two exceptions to the catch, but can't get that to work.
You could just turn your int into a String and check if it has a decimal point or a negative sign.
Scanner input = new Scanner(System.in);
int l;
while (true)
{
l = input.nextInt();
if ((""+l).indexOf('.') >= 0 || (""+l).indexOf('-') >= 0)
{
System.out.println(/*your message here*/);
}
else
{
break;
}
}
//continue with your program
Edit: Syntax
Try this:
if (input < 0){
throw new IllegalArgumentException("Input cannot be negative.");
}
If the number is negative, it will throw the exception and then the catch code can be executed.
This question already has answers here:
What is a NumberFormatException and how can I fix it?
(9 answers)
Closed 6 years ago.
I'm not sure how to set it up, but my method has a user input a number between a minimum and maximum, although I have no idea how to handle the NumberFormatException with a try-catch block. Are there any suggestions in regards to how this can be fixed?
static int promptForInt(String prompt, int min, int max){
System.out.println(prompt);
String input = in.readLine();
int parsedInt = Integer.parseInt(input);
while(!(parsedInt > min && parsedInt < max)){
System.out.println("Your input is invalid. " + prompt);
input = in.readLine();
parsedInt = Integer.parseInt(input);
}
return parsedInt;
}
static int promptForInt(String prompt, int min, int max){
System.out.println(prompt);
String input = in.readLine();
int parsedInt;
boolean exceptionThrown = false;
do {
try {
parsedInt = Integer.parseInt(input);
} catch(NumberFormatException e) {
exceptionThrown = true;
}
if (exceptionThrown || (!(parsedInt > min && parsedInt < max)) {
System.out.println("Your input is invalid. " + prompt);
input = in.readLine();
parsedInt = Integer.parseInt(input);
} else {
return parsedInt;
}
} while(true)
}
From my post about NumberFormatException:
Ad. 4.
Finally we come to the place in which we agree, that we can't avoid situations when it's user typing "abc" as a numeric string. Why? Because he can. In a lucky case, it's because he's a tester or simply a geek. In a bad case it's the attacker.
What can I do now? Well, Java gives us try-catch you can do the following:
try {
i = Integer.parseInt(myString);
} catch (NumberFormatException e) {
e.printStackTrace();
//somehow workout the issue with an improper input. It's up to your business logic.
}
Exceptions
In Java Exceptions are used for marking unexpected situations. For example parsing non-numeric String to a number (NumberFormatException) or calling a method on a null reference (NullPointerException). You can catch them in many ways.
try{
//some code
} catch (NumberFormatException e1) {
e.printStackTrace() //very important - handles the Exception but prints the information!
} catch (NullPointerException e2) {
e.printStackTrace();
}
or using the fact, that they all extend Exception:
try {
//somecode
} catch (Exception e) {
e.printStackTrace;
};
or since Java 7:
try {
//somecode
} catch (NullPointerException | NumberFormatException e) {
e.printStackTrace;
};
Exceptions can be easier to deal with if you think of them as the method "Trying to do something, but it couldn't because of X". X is the exception.
The below code could be one way you modify your code to handle the exception:
static int promptForInt(String prompt, int min, int max) {
Integer parsedInt = null; // use an Integer so null can be used to mean an invalid value
while (parsedInt == null) {
System.out.println(prompt);
String input = in.readLine();
int temp;
try {
temp = Integer.parseInt(input);
} catch(NumberFormatException e) {
System.out.print(input+" is not a number. ");
continue;
}
if (temp < min || temp > max) {
System.out.print("Your number must be between "+min+" and "+max+" (inclusive). ");
} else {
parsedInt = temp;
}
}
return parsedInt;
}
Some things you should notice: Firstly, you have not defined in. You could do that like so:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
If you do that, you'll soon see that you have another Exception to deal with: this can throw UnsupportedEncodingException, and also readLine can throw IOException.
Your method must return a valid integer or it will not exit (you really should supply the user some means of exiting the loop without entering a valid number). Since that's not going to be possible if, for instance, you couldn't read anything from System.in your method needs a reasonable way of telling the caller: "I tried to get an int from the user, except I was stopped by X".
You may actually end up doing something more like:
static int promptForInt(String prompt, int min, int max) throws UserInputException {
BufferedReader in;
try {
in = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
} catch(UnsupportedEncodingException unsupported) {
// create a new exception and supply the cause as an inner exception
throw new UserInputException("Could not open a reader for System.in", unsupported);
}
Integer parsedInt = null; // use an Integer so null can be used to mean an invalid value
while (parsedInt == null) {
System.out.println(prompt);
String input;
try {
input = in.readLine();
} catch (IOException ioException) {
throw new UserInputException("Could not read a line", ioException);
}
if (input.length() == 0) {
throw new UserInputException("User aborted input");
}
int temp;
try {
temp = Integer.parseInt(input);
} catch(NumberFormatException e) {
System.out.print(input+" is not a number. ");
continue;
}
if (temp < min || temp > max) {
System.out.print("Your number must be between "+min+" and "+max+" (inclusive). ");
} else {
parsedInt = temp;
}
}
return parsedInt;
}
I am trying to create a code where an int is supposed to be entered and then have exceptions for if the int is not between 9 and 99, another exception if a double is entered instead of int and then a third exception if a string is entered. How do i do this? i have below what i have so far but am not sure how to correct it. thanks
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean correct = true;
do {
try {
System.out.println("Enter an Integer between 9 and 99");
int number = input.nextInt();
if (number >= 9 && number <= 99) {
System.out.println("Thank you, Initialization completed");
correct = false;
} else if (number < 9 || number > 99) {
throw new Exception("Integer is not within the range");
}
if (input.hasNextDouble()) {
throw new Exception("Integer not entered");
} else {
correct = false;
}
if (input.hasNext("")) {
throw new NumberFormatException("Integer not entered");
} else {
correct = false;
}
} // check for range
catch (Exception e1) {
System.out.println("Number is not within 9 and 99");
System.out.println();
input.nextLine();
} catch (Exception e2) {
System.out.println("An integer was not entered");
System.out.println();
input.nextLine();
} catch (NumberFormatException e3) {
System.out.println("An integer was not entered");
System.out.println();
input.nextLine();
}
} while (correct);
}
Method .getMessage() returns the string given in constructor:
throw new Exception("HERE");
When you catch Exception, you catch also NumberFormatException, InputMismatchException, etc.
so you must catch broader ones last.
catch (NumberFormatException e3) { // Precisier goes first
System.out.println("An integer was not entered");
System.out.println();
input.nextLine();
}
catch (Exception e1) {
System.out.println(e1.getMessage());
System.out.println();
input.nextLine();
}
I would like to know how to set up a try/catch on a variable that is a string but has to be checked against an integer like so:
public static void isValidAge(String age) {
int age2 = Integer.parseInt(age);
try {
if(age2 <= 0 || age2 >= 150) {
throw new NumberFormatException();
}
}
catch (NumberFormatException ex) {
if(age2 <= 0) {
System.err.print("Age can not be 0 or negative.");
}
else if (age2 >= 150) {
System.err.print("Age can not be equal to or more than 150.");
}
else if (age.contains("##$")) {
System.err.print("You did not enter a valid age.");
}
}
}
The try/catch must also be able to handle characters and keep the program running still.
The try-catch should be on the parse attempt itself:
int age2 = -1; //set to an invalid value
try
{
age2 = Integer.parseInt(age);
}
catch(Exception ex)
{
System.out.println("Error: Could not parse age to number, exiting");
return; //exit function
}