Prevent user from inputting value larger than int max? - java

I have some cool code that takes an int value. I let my little brother test it, and what is the first thing he does? He enters this:
12345678910
And he got this error:
User did not input a number. (Error Code 1)
Well that's not true. Is there a way to give him a different error for "value too large"? Here's my code:
try
{
number = input.nextInt();
}
catch (InputMismatchException e)
{
System.err.println("User did not input a number. (Error Code 1)");
System.exit(1);
}
Thanks!
EDIT
The code that was posted that I used has been modified. This is the code I ended up going with, but the solution is no longer in the comments.
try
{
double intitalinput = input.nextDouble();
if (intitalinput > Integer.MAX_VALUE)
{
System.err.println("User entered a number larger than " + Integer.MAX_VALUE + ". (Error Code 2)");
System.exit(2);
}
else
{
number = (int) intitalinput;
}
}
catch (InputMismatchException e)
{
System.err.println("User did not input a number. (Error Code 1)");
System.exit(1);
}
Thank you to Jay Harris for solving my issue!
EDIT THE SECOND
I added a 'less than zero' check. In case anyone else stumbles upon this question wanting similar help, I'll show the updated code here:
try
{
double intitalinput = input.nextDouble();
if (intitalinput > Integer.MAX_VALUE)
{
System.err.println("User entered a number larger than " + Integer.MAX_VALUE + ". (Error Code 2)");
System.exit(2);
}
else if (intitalinput < 0)
{
System.err.println("User entered a number smaller than 0. (Error Code 3)");
System.exit(3);
}
else
{
number = (int) intitalinput;
}
}
catch (InputMismatchException e)
{
System.err.println("User did not input a number. (Error Code 1)");
System.exit(1);
}

There is plenty of ways to achieve this, for instance check for a larger number and validate it against the max and min size of a Integer using Integer.MAX_VALUE and Integer.MIN_VALUE.
// long userInput = input.nextLong()
// or
double userInput = input.nextDouble();
// expecting an integer but user put a value larger than integer
if (userInput > Integer.MAX_VALUE || userInput < Integer.MIN_VALUE) {
// Throw your error
} else {
// continue your code the number is an int
number = (int) userInput;
}

You could try to get a long instead, but that would only raise the limit, not solve the problem.
The other way would be to get the value as a String and check if its numeric using some regular expression befor trying to convert it. if the conversion fails then the number is to big.

Try using the Scanner.hasNextInt() method:
From http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#hasNextInt()
Returns true if the next token in this scanner's input can be interpreted as an int value in the default radix using the nextInt() method. The scanner does not advance past any input.
if (input.hasNextInt()) {
number = input.nextInt();
} else {
System.err.println("User did not input a number. (Error Code 1)");
System.exit(1);
}
If you want to detect that a number was entered, but that it might be too large to parse, try this approach:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter a number:");
if (input.hasNextInt()) {
int num = input.nextInt();
System.out.println("num is " + num);
} else {
String s = input.next();
boolean isaNumber = true;
for (int i=0; i<s.length(); i++) {
if (!Character.isDigit(s.charAt(i))) {
isaNumber = false;
break;
}
}
if (isaNumber) {
System.out.println("It appears you entered a number, but it canntot "
+ "be read. It might be too large.");
} else {
System.out.println("Error parsing number.");
}
}
}
Here, I simply check if each character in the input is a digit. If so, I assume it is a number. This code could certainly be cleaned-up, and probably is not 100% bullet-proof. I just wanted to illustrate on possible approach to your question.

As shown in this answer, you could store the input in a long instead, and then check if the number is too big. Or, you could just change all your values to a long type.

A large number will not return an exception from the compiler by itself; the error you ran into may be because an int cannot hold values exceeding around 2 billion. Instead you can try declaring number as a long type.
Another solution would be to first grab the input with a string, as #karfau stated. This could be done specifically by using the length() method; if the string exceeds a certain number of characters, you will know that the input is too long.

You could surround it with a try-catch block.
See the 1st answer to this question for more detailed info.

Related

JavaFX is working but the try-catch-finally code isn't

I just started my lesson about exception handling and I'm unsure of what I did wrong in my code -- what I'm aiming to do is to create a UI that asks the user how many pets they own, and checks if the input is an integer. Can anyone point out what's wrong?
I've already tried using label.setText() for my message, and I've also changed the exception I used (I tried NumberFormat).
Here's the block I used (this is the first time I encountered EH, so I find this topic kind of confusing)
String value = input.getText();
int intval = 0;
intval = Integer.parseInt(value);
try {
if (0 >= intval) {
throw new IllegalArgumentException();
}
else
throw new InputMismatchException();
}
catch(IllegalArgumentException e)
{
String outputMessage = "The number must be an integer no less than 0!";
label1.setText(outputMessage);
}
catch(InputMismatchException i) {
System.out.println("Please enter an integer.");
System.out.println("You entered: " + intval);
}
finally
{
System.out.println("You own " + intval + " pets.");
}
The exceptions I want to include are if the user entered another number type instead of an integer, and if the user entered a negative integer instead of a positive one or 0. My code runs, but the try-catch block doesn't really work.
Looks like there are lot of defects in this code! First of all you shouldn't have taken the input as String if you would have taken the input as integer you could have raised the InputMismatchException by which you could have easily told the user saying "enter only integer value", by taking input as the string you will not be able to do that.
Don't use finally block, because no matter how many exceptions are throw by your code the finally block will get executed. Even if you entered -1 at last(while executing the code) it will show "you have -1 pets:" message, as finally block gets executed not matter what happens!
I refactored the code to make it work the same way
Scanner input = new Scanner(System.in);
boolean exceptionHit = false;
int value = 0;
try {
value = input.nextInt();
if (value <= 0) {
throw new IllegalArgumentException();
}
}
catch (IllegalArgumentException e) {
String outputMessage = "The number must be an integer no less than 0!";
label1.setText(outputMessage);
exceptionHit = true;
} catch (InputMismatchException i) {
System.out.println("Please enter an integer.");
exceptionHit = true;
}
if (exceptionHit == false)
System.out.println("You have " + value + " pets");
I have removed finally block so the last message will not be displayed every time! I have added a boolean value instead of it which will be set to true if any exception is hit.

Java Scanner try catch multiple data types

First of all thanks for everything you, guys are doing here on stack overflow. It helped me a lot many times!
My problem today is a little issue with try/catch instruction using along with Scanner. Take a look at my method for adding products to a recipe:
public static void addProducts(List<Product> product, Scanner sc)
{
if (run == true)
{
Maths calc = new Maths();
//Some instructions in Polish, not needed here :)
while (true)
{
String name = null;
double quantity = 0;
double pricePerUnit = 0;
try
{
name = sc.nextLine();
if (name.equals("0") || name.equals("exit"))
{
Logic.run = false;
break;
}
quantity = sc.nextDouble();
sc.nextLine();
pricePerUnit = sc.nextDouble();
sc.nextLine();
product.add(new Product(product.size() + 1, name, calc.round(quantity, 2), calc.round(pricePerUnit, 2)));
System.out.println("Product added: " + "\n" + product.get(product.size() - 1));
} catch (InputMismatchException e)
{
System.out.println("Error! Please repeat your last input.");
}
}
double num = 0;
for (Product p : product)
{
num += p.getPrice();
}
Maths.setTotalPrice(num);
System.out.println("Total: " + num);
} else
{
System.out.println("You have already added products to the recipe!");
}
}
As you can see im reading String, double and double in the try/catch instruction. For example when adding "potatoes" to the recipe I accidentaly write "horse" where quantity should be I get a product named "horse" instead of "potatoes". Is that clear? I have a yellow duck right here but its easier to explain in my native language than it is in English :)
If there is anything unclear I will do my best to explaing, thanks!
When you do:
quantity = sc.nextDouble();
sc.nextLine();
you're throwing away any extra input, without acknowledgement. If you want to restrict user to only enter a number and nothing else on a line, use:
quantity = Double.parseDouble(sc.nextLine()); // maybe add .trim()
If you leave your code unchanged, remember that when InputMismatchException is thrown, the Scanner is still sitting on (at beginning of) the bad input, so you need to discard that:
} catch (InputMismatchException e)
{
System.out.println("Error! Please repeat your last input.");
sc.nextLine(); // discard bad input
}
Of course, your code will loop around and prompt for all 3 inputs, so error message is a bit misleading.

How can I set limits on how many characters can be inputted? (Java)

do{
out.println("\n---------------------------------");
out.println("---------------------------------");
out.print("Please type your acces card number: ");
try{
card = input.nextInt();
if(card.length != 10){
out.println("The number you typed is incorrect");
out.println("The number must be 10 numbers long");
continue;
}
}
catch(InputMismatchException ex){
}
}while(true);
Im trying to make card be 10 characters long. Like (1234567890), and if the user inputs (123) or (123456789098723) an error message should appear. card.length doesnt seem to work.
Just change int to String
String card = input.next();
if(card.length() != 10){
//Do something
}
You can easily convert it to int later
int value = Integer.parseInt(card);
You could change
if(card.length != 10){
to something like
if(Integer.toString(card).length() != 10){
Of course, it's possible the user entered
0000000001
which would be the same as 1. You could try
String card = input.next(); // <-- as a String
then
if (card.length() == 10)
and finally
Integer.parseInt(card)
In Java, you cannot get the length of an int. The easiest way to find the number of digits is to convert it to a String. However, you can also do some math to find out the number's length. You can find more information here.
You cannot get the length of an int. It would be much better to get input as a String, and convert it into an int later on, if the need arises. You can do the error checking in your while loop, and if you like short circuiting, you can have the while check display your error message too:
out.println("\n---------------------------------");
out.println("---------------------------------");
out.print("Please type your access card number: ");
do {
try {
card = input.nextLine();
} catch (InputMismatchException ex) {
continue;
}
} while ( card.length() != 10 && errorMessage());
And have your errorMessage function return true, and display the error messages:
private boolean errorMessage()
{
out.println("The number you typed is incorrect");
out.println("The number must be 10 numbers long");
return true;
}

Throw an error when a string is entered instead of an int [duplicate]

This question already has answers here:
Java input mismatch error using scanner
(3 answers)
Closed 8 years ago.
I am working on homework for my class. I have written a method to throw an error if an incorrect integer is entered and I am trying to give an error message when a string is entered instead of an int but I am not sure how. I am not allowed to use parsInt or built in string methods. I would be grateful for any help.
int playerNum = stdin.nextInt();
while (invalidInteger(playerNum) == -1 || invalidInteger(playerNum) == -2 || invalidInteger(playerNum) == -3)
{
if(invalidInteger(playerNum) == -1)
{
System.out.println("Invalid guess. Must be a positive integer.");
System.out.println("Type your guess, must be a 4-digit number consisting of distinct digits.");
count++;
}
if(invalidInteger(playerNum) == -2)
{
System.out.println("Invalid guess. Must be a four digit integer.");
System.out.println("Type your guess, must be a four digit number consisting of distinct digits.");
count++;
}
if(invalidInteger(playerNum) == -3)
{
System.out.println("Invalid guess. Must have distinct digits.");
System.out.println("Type your guess, must be a four digit number consisting of distinct digits.");
count++;
}
playerNum = stdin.nextInt();
}
Added this snippet to catch the exception. Thanks to almas shaikh.
try {
int playerNum = scanner.nextInt();
//futher code
} catch (InputMismatchException nfe) {
System.out.println("You have entered a non numeric field value");
}
Use the following code:
try {
int playerNum = scanner.nextInt();
//futher code
} catch (InputMismatchException nfe) {
System.out.println("You have entered a non numeric field value");
}
Scanner throws InputMismatchException when you enter string instead of integer. So very next time when you try to enter String it will throw the InputMismatchException exception, you could catch the exception and say you let user know that user has entered invalid input and let him retry.
Check the java doc for nextInt() -- is stdin a Scanner? If so, nextint() will throw an exception if some non-integer text is entered. You would probably want to catch that and print your own pretty error. Though, you might be going even further than the assignment expects. The phrase "throw an error if an incorrect integer is entered" might imply that only integers will be entered. It depends on the instructor/class.
import java.util.*;
public class Test
{
public static void main(String args[])
{
Scanner in = new Scanner(System.in);
try
{
int i = in.nextInt();
}
catch(InputMismatchException e)
{
e.printStackTrace();
}
}
}
I hope this will server as an example. When you give an char or string. exception is raised.
Well, you can use next() to get the value as a String, then parse the value and see if a String or Integer was entered.
String str = stdin.next();
for (char c:str.toCharArray()) {
if (!Character.isDigit(c)) {
throw new IllegalArgumentException("Invalid character entered: " + c);
}
}

Try-Catch inside a loop

In the below code, I ask the user to give an integer input and if the input is 0 or a negative number, it loops again until the positive number is given. The thing is that if the users presses a letter, my code crashes and despite the fact that I used try-catch in a lot of ways nothing really worked. Any ideas?
I used try-catch inside the loop, but it only worked for one letter input and not correctly.
System.out.print("Enter the number of people: ");
numberOfPeople = input.nextInt();
while (numberOfPeople <= 0) {
System.out.print("Wrong input! Enter the number of people again: ");
numberOfPeople = input.nextInt();
}
The problem in your current code is that you're always trying to read an int so when receiving a non-integer input you can't handle the error in the right way. Modify this to always read a String and convert it into an int:
int numberOfPeople = 0;
while (numberOfPeople <= 0) {
try {
System.out.print("Enter the number of people: ");
numberOfPeople = Integer.parseInt(input.nextLine());
} catch (Exception e) {
System.out.print("Wrong input!");
numberOfPeople = 0;
}
}
//continue with your life...

Categories

Resources