I am making a simple program that lets you add the results of a race, and how many seconds they used to finish. So to enter the time, I did this:
int time = Integer.parseInt(JOptionPane.showInputDialog("Enter seconds"));
So my question is, how can I display an error message to the user if he enters something other than a positive number? Like a MessageDialog that will give you the error until you enter a number.
int time;
try {
time = Integer.parseInt(JOptionPane.showInputDialog("Enter seconds"));
} catch (NumberFormatException e) {
//error
}
Integer.parseInt will throw a NumberFormatException if it can't parse the int.
If you just want to retry if the input is invalid, wrap it in a while loop like this:
boolean valid = false;
while (!valid) {
int time;
try {
time = Integer.parseInt(JOptionPane.showInputDialog("Enter seconds"));
if (time >= 0) valid = true;
} catch (NumberFormatException e) {
//error
JOptionPane.showConfirmDialog("Error, not a number. Please try again.");
}
}
Integer.parseInt Throws NumberFormatException when the parameter to Integer.parseInt is not a integer, Use try Catch and display required error message, keep it in do while loop as below
int time = -1;
do{
try{
time = Integer.parseInt(JOptionPane.showInputDialog("Enter seconds"));
}
catch(NumberFormatException e){
}
}while(time<=0);
If JOptionPane.showInputDialog("Enter seconds") is not a valid number, you will be getting NumberFormatException.For positive number check, just check time >=0
Depends on how you want to solve it.
An easy way is to declare time as an Integer and just do:
Integer time;
while (time == null || time < 0) {
Ints.tryParse(JOptionPane.showInputDialog("Enter seconds"));
}
Of course that would require you to use google guava. (which contains a lot of other useful functions).
Another way is to use the above code but use the standard tryparse, catch the NumberFormatException and do nothing in the catch.
There are plenty of ways to solve this issue.
Or not reinvent the wheel and just use:
NumberUtils.isNumber or StringUtils.isNumeric from Apache Commons Lang.
Related
I am trying to program a method that handles user Input. The method needs to scan from the console an int, check if scanned int was in Range and then check the validity of the data before scanning another int in another method. I decided to program the method recursively, that it will call itself to repeat if the mentioned conditions are not met.
public static void readUserInputDay(Scanner scanner) {
System.out.print("Day (1-31): ");
try {
int tmp = scanner.nextInt();
day = new Integer(tmp);
if(isTheInputInRange(day.intValue(), DAY)) {
readUserInputMonth(scanner);
} else {
System.out.print("Number isn't in Range (1-31)\n");
readUserInputDay(scanner);
}
} catch (Exception e) {
System.out.print("Please enter a number!\n");
readUserInputDay(scanner);
}
}
The other filters work as expected, however if I enter on the console something that is not an int the Exception is triggered and catched (As expected) but when I expect the Method to recursively repeat itself, I instead get the following output on the console:
Day (1-31): Please enter a number!
Day (1-31): Please enter a number!
Day (1-31): Please enter a number!
Exception in thread "main" java.lang.StackOverflowError
at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:77)
at sun.nio.cs.UTF_8.access$200(UTF_8.java:57)
at sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(UTF_8.java:636)
at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:691)
at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:579)
at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:271)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
at java.io.PrintStream.write(PrintStream.java:526)
at java.io.PrintStream.print(PrintStream.java:669)
at MyClass.readUserInputDay(MyClass.java:27)
at MyClass.readUserInputDay(MyClass.java:43)
at MyClass.readUserInputDay(MyClass.java:43)
Do have any ideas how I need to fix the code, so when method call itself, it doesn't enter immediately in the catch block ?
Thanks in advance
you are calling the method inside of itself 3 times and according to conditions it cause to re-call it self and at the end overflow error.
to prevent from this problem at first try to change the structure of your code and use while loops for example to continue your code at a certain condition you want and get the result:
public static void readUserInputDay(Scanner scanner) {
try {
boolean isFinished = false;
// your condition for loop
while (!isFinished) {
System.out.print("Day (1-31): ");
int tmp = scanner.nextInt();
day = new Integer(tmp);
if (isTheInputInRange(day.intValue(), DAY)) {
readUserInputMonth(scanner);
isFinished = true;
} else {
System.out.print("Number isn't in Range (1-31)\n");
}
}
} catch (Exception e) {
System.out.print("Please enter a number!\n");
readUserInputDay(scanner);
}
}
It is odd that you say the StackOverflow error occurs on the first retry, especially within the first System.out.print call.
However, as Mustafa suggested, using a while loop rather than recursion is a much better choice in this case, as it will not cause new stack frames to be created every time somebody enters the wrong text (as I do not think that Java can do tail call optimisation on that method).
public static void readUserInputDay(Scanner scanner) {
while (true) {
System.out.print("Day (1-31): ");
try {
int tmp = scanner.nextInt();
day = new Integer(tmp);
if (isTheInputInRange(day.intValue(), DAY)) {
readUserInputMonth(scanner);
break; // exit the retry loop
} else {
System.out.print("Number isn't in Range (1-31)\n");
}
} catch (Exception e) {
System.out.print("Please enter a number!\n");
}
// By this point, the input is invalid, so loop again
}
}
I was able to add a try catch that tells the user that they cant use
letters.However for some reason adding a try catch for negative numbers dosent seem to work.I know that the try block is where if somthing can go wrong like entering in a negative number the catch can print out the error message. I think thats where my problem lies. Another problem that is associated with the try catch is that I'm use to the user entering in -1 to enter the contents that the user inputs so I'm thinking its gonna cause a logical problem.
tl;dr Adding a try catch or another catch to prevent user from adding negative numbers
this is not the the whole program but what it does is that it filters out the integers that the user inputs and separates the evens and odds.
public static void main(String [] args)
{
Scanner stdin = new Scanner(System.in);//for user input
int[] evenNum = new int [100];//Even Array up too 100
int[] oddNum = new int[100];//Odd Array up too 100
int evenIndex=0;//even numbers
int input=0;//user input
int i=0;//incrementer for arrays
int k=0;
int j=0;
String name;
System.out.println("Type In Your Name");//Type in name
name = stdin.nextLine();
while ((i < oddNum.length && i < evenNum.length) && input !=-1)//100 numbers only
{
try{//this is what we want anything else the catch will block it and display a message
System.out.println(name+" Enter a positive number, Enter -1 For results");
input= stdin.nextInt();
oddNum[i]=input;//holds input
i++;//Increments array
}
catch(Exception d){
System.out.println("Only Positive Numbers & no Letters Please!");
stdin.next();
}
}
You can check the input variable after you get it from the scanner
if (input < 0) {
System.out.println("Only Positive Numbers & no Letters Please!");
}
Your code does not throw any Exception when the number is read from the scanner. So you cannot expect that the execution jumps into the catch-block when you enter a negative number.
But you can alternatively throw an exception when the input is negative. This will make the thread to jump directly into the catch-block. In the catch-block you can then print the message you passed the IllegalArgumentException
if (input < 0) {
// this gets caught in the catch block
throw new IllegalArgumentException("Only Positive Numbers & no Letters Please!");
}
...
} catch (IllegarArgumentException e) {
System.out.println(e.getMessage());
}
It is generally bad practice to catch Exception (java.lang.Exception). This is the "root" of all checked exceptions and the catch-block will be jumped into whenever any subclass of Exception is thrown.
Just catch the concrete exception that you are expecting. (In this case IllegalArgumentException.)
Also you should not use exceptions to control the execution flow of your program.
I would suggest something like this:
do {
System.out.println(name+" Enter a positive number, Enter -1 For results");
try {
input = stdin.nextInt();
} catch (java.util.InputMismatchException e) { // if the user enters something that is not an integer
System.out.println("Please only enter integers");
input = Integer.MIN_VALUE;
stdin.next(); // consume the non-int so we don't get caught in an endless loop
}
} while (input < -1); // loop as long as the input is less than -1
if (input == -1) {
// show the results here
}
This will accept positive integers and will prompt for an input until the user enters a positive number, 0 (zero) or -1 (which should show the results)
You can do it like this:
if (input < 0) {
throw new IllegalArgumentException();
}
Now if the number is negative, it will throw exception and the catch code can be executed. Because you catch Exception so all of the exception will be catches here.
Note: In catch block you no need to add stdin.next(); because the program will continue from the first line of while loop.
In order for your catch block to catch exception, the Exception needs to be thrown from the code. In case of negative numbers the line input= stdin.nextInt(); will not throw exception as it is perfectly legal for integer to be negative. You will need to add if condition like this:
input = stdin.nextInt();
if ( input < 0 ) {
throw new Exception("Negative number entered");
}
But some consider this to be bad practice because you are using exceptions to control the flow of a program. So I give you another example how you can do this without throwing an exception:
input = stdin.nextInt();
if ( input < 0 ) {
System.out.println("Only Positive Numbers Please");
continue; // will continue from the beginning of a loop
}
I want to make a try-catch exception that only accept 1-5 or 9 input. So I wrote the following code.
try {
step1 = scanner.nextInt();
} catch (Exception ex) {
System.out.println("Error! Input accept integers only. Input 1-5 or 9");
System.out.println("");
continue;
}
The result is that if I input an invalid number, it gave me an error (That's true). But when I input a character, it gave me an infinite loop. How can I solve the problem?
Since i don´t know how your loop looks i´ll just go with an endless loop in my answer. In the normal case, the nextInt method wont catch the carriage return, and if you input something that is not a number you need to call nextLine to catch this. If you don´t do this you might run into an infinity loop if you are using any kind of loop that just asks for nextInt. This could solve the problem:
while(true) {
int step1;
try {
step1 = s.nextInt();
} catch (InputMismatchException e) {
System.out.println("Error! Input accept integers only. Input 1-5 or 9");
System.out.println("");
} finally { // Use a finally block to catch the carriage return, no matter if the int that got input was valid or not.
s.nextLine();
}
}
Maybe you must parse input before decision making.
Sorry for my bad English, I'm not a native speaker also.
try this, which make all the tests
int step1;
while (true)
{
Scanner scanner = new Scanner(System.in);
try {
step1 = scanner.nextInt();
if (((step1>=1) && (step1<=5)) || (step1==9))
// BINGO
break;
}
catch (Exception ex)
{
}
System.out.println("Error! Input accept integers only. Input 1-5 or 9");
System.out.println("");
// it loops ther
}
System.out.println("You are done ! "+step1);
I've finished a simple program that converts a decimal number to binary (32bit). I would like to implement some type of error message should the user enter in an overflow number (anything over 2147483647). I tried a if_else , loop, but quickly found out I couldn't even do that. So I messed with taking the input as a string, and then using some things like .valueOF() etc, and still can't seem to get around to the solution.
I don't see how I can compare any value to a >2147483648 if I can't store the value in the first place.
Here's the bare code I have for the getDecimal() method:
numberIn = scan.nextInt();
Edit:: After trying the try / catch method, running into a compile error of
"non-static method nextInt() cannot be referenced from a static context".
My code is below.
public void getDec()
{
System.out.println("\nPlease enter the number to wish to convert: ");
try{
numberIn = Scanner.nextInt();
}
catch (InputMismatchException e){
System.out.println("Invalid Input for a Decimal Value");
}
}
You can use Scanner.hasNextInt() method, which returns false, if the next token cannot be converted to an int. Then in the else block, you can read the input as string using Scanner.nextLine() and print it with an appropriate error message. Personally, I prefer this method :
if (scanner.hasNextInt()) {
a = scanner.nextInt();
} else {
// Can't read the input as int.
// Read it rather as String, and display the error message
String str = scanner.nextLine();
System.out.println(String.format("Invalid input: %s cannot be converted to an int.", str));
}
Another way to achieve this is of course, using try-catch block. Scanner#nextInt() method throws an InputMismatchException, when it can't convert the given input into an integer. So, you just need to handle InputMismatchException: -
try {
int a = scan.nextInt();
} catch (InputMismatchException e) {
System.out.println("Invalid argument for an int");
}
I suggest you surround that statement with a try/catch block for NumberFormatException.
Like so:
try {
numberIn = Integer.valueOf(scan.next());
}catch(NumberFormatException ex) {
System.out.println("Could not parse integer or integer out of range!");
}
use exceptions.. whenever a number is entered more than its storing capacity then exception will be raised
Refer docs.oracle.com/javase/tutorial/essential/exceptions/
You can user hasNextInt() method to make sure that there is an integer ready to be read.
try this :
long num=(long)scan.nextLong();
if (num > Integer.MAX_VALUE){
print error.
}
else
int x=(int)num;
or try catch:
try{
int number=scan.nextInt()
}
}catch(Exception ex){
print the error
}
i've found this line of code got error if the input not an number
int sum = Integer.parseInt(request.getParameter("sum"));
the error message is
type Exception report
message
descriptionThe server encountered an internal error () that prevented it from fulfilling this request.
exception
org.apache.jasper.JasperException: java.lang.NumberFormatException: For input string: "a"
root cause
java.lang.NumberFormatException: For input string: "a"
how to handle the input if the input is a string or null?
thanks
You should first make sure request parameter is not null and contains numbers only using:
if (request.getParameter("sum") != null &&
request.getParameter("sum").matches("^\\d+$"))
int sum = Integer.parseInt(request.getParameter("sum"));
Try:
int sum = 0;
try {
sum = Integer.parseInt(request.getParameter("sum"));
}
catch (NumberFormatException e) {
// sum = 0. If you needed to do anything else for invalid input
// put it here.
}
It really depends on what should be done if sum is not a number.
try{
int sum = Integer.parseInt(request.getParameter("sum"));
}
catch(Exception e)
{
//how do you want to handle it? like ask the user to re-enter the values
}
Just catch the exception and handle it accordingly:
int sum;
try {
sum = Integer.parseInt(request.getParameter("sum"));
}
catch {
//do something if invalid sum
}
Check manually (loop over the characters)
Catch the exception
Try this:
try {
sum = Integer.parseInt(request.getParameter("sum"));
} catch (NumberFormatException e) {
... // handle if the string isn't a number
} catch (NullPointerException e) {
... // handle if it's null
}
Check for null before Using Intefer.parseInt and also you can check whether input contains other than numeric value
Here's a different approach that doesn't involve throwing and catching exceptions:
String input = request.getParameter("sum");
// Validate the input using regex
if (input == null || !input.matches("^-?\\d{1,8}$")) {
// handle bad input, eg throw exception or whatever you like
}
int sum = Integer.parseInt(input);
Note that this regex doesn't allow numbers too large, and allows negative numbers
I see the org.apache.jasper.JasperException Which means this is in a JSP? If you're adding code like that to a JSP, you might want to reconsider what you're doing. Ideally, you should handle things like input validation in a controller of some sort, and then pass off results to a template of JSP for rendering.
There are many frameworks out there to help with this sort of thing, and in general they're worth using because your web application will benefit from all of the work that the framework authors have already done in the realm of security etc...
Pretty much any of the half a dozen code answers already posted will work for you though if you just want to hack it out.