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.
Related
I'm having trouble with my exception handling. The program runs fine if I input a number but create an infinite loop if a character is entered.
boolean ask= true;
while(ask)
{
ask = false;
try
{
System.out.println("What is the age?");
int age = input.nextInt();
setAge(age);
}catch(InputMismatchException e) {
System.out.println("Invalid input!");
ask = true;
}
}//end while
Try below code:
boolean ask= false;
while(!ask)
{
try
{
System.out.println("What is the age?");
int age = input.nextInt();//does not read the newline character in your input created by hitting "Enter,"
setAge(age);
ask = true;
}catch(InputMismatchException e) {
System.out.println("Invalid input!");
input.nextLine();//consumes the \n character
}
}//end while
Let's say you enter "abc"
Your call to input.nextInt() causes the scanner to look at the a and say "That's not an int, so I will throw an exception."
In the exception handler, you set ask to true so the loop repeats.
When the loop repeats, the scanner looks at that exact same a again, and it says "That's not an int, so I will throw an exception."
In the exception handler, you set ask to true so the loop repeats.
And so on....
That pesky a never gets consumed by the scanner.
From the source code of nextInt:
public int nextInt(int radix) {
// Check cached result
if ((typeCache != null) && (typeCache instanceof Integer)
&& this.radix == radix) {
int val = ((Integer)typeCache).intValue();
useTypeCache();
return val;
}
setRadix(radix);
clearCaches();
// Search for next int
try {
String s = next(integerPattern());
if (matcher.group(SIMPLE_GROUP_INDEX) == null)
s = processIntegerToken(s);
return Integer.parseInt(s, radix);
} catch (NumberFormatException nfe) {
position = matcher.start(); // don't skip bad token
throw new InputMismatchException(nfe.getMessage());
}
}
It uses Integer.parseInt(s, radix); to produce the result.
If call Integer.parseInt("s"); will result:
Exception in thread "main" java.lang.NumberFormatException: For input string: "s"
I am trying to create a custom exception class and I'm having a lot of trouble. Can someone help me out! I just started programming very recently and i'm hoping to get some pointers.
import java.util.Random;
import java.util.Scanner;
import java.util.InputMismatchException;
public class GuessingGame {
public static void main(String[]args) throws BadGuessException
{
int min = 1;
int max = 10;
Random rand = new Random();
int numberToGuess = rand.nextInt((max - min) + 1) + min;
Scanner input = new Scanner(System.in);
int guess;
boolean win = false;
int numberOfTries = 0;
while (!win)
{
System.out.println("Guess a number between 1 and 10: ");
try
{
guess = input.nextInt();
numberOfTries++;
if (guess == numberToGuess)
{
win = true;
System.out.println("YOU GOT IT!");
System.out.println("It took you " + numberOfTries + " tires.");
}
else
{
throw new BadGuessException();
}
}
catch(InputMismatchException e)
{
e.getMessage();
}
}
}
}
import java.util.*;
public class BadGuessException extends Exception {
String message = "Sorry, that was an invalid guess!";
//Default Constructor
public BadGuessException()
{
super();
}
//Parameterized Constructor
public BadGuessException(Throwable cause)
{
super(cause);
}
}
I'm supposed to create 2 constructors, one default and one parametrized. If the user enters a number between 1-10, i should catch it in a catch block and print the message "invalid guess" And if they enter a letter or something, the output should be something like "Invalid input" ( Should I catch invalid input in BadGuessException and then pass it to InputMismmatch? If so, how do I do that?)
Right now, when I run this code, if I enter a letter, it doesn't crash, but the while loop iterates continuously and I'm not able to enter anymore inputs. It just keeps repeating "Guess a number between 1-10."
I'm assuming it's because once the try block executes once, it doesn't execute again? How do I fix this? Sorry for any confusion, happy to clarify! any help is much appreciated.
Also, I'm not sure how to catch 2 different exceptions at the same time. One for invalid guess and one for invalid input. :/
Exceptions should be used for handling errors, invalid input, illegal, unusual situations. If not guessing the correct number is an error, that sounds like not being a mind reader is an error. So BadGuessException is misused here.
For a better use case, how about throwing this exception for non-sense input? For example, since the program asks the user to input a number between 1 and 10, inputting -3 or 99 would be clearly an error.
The loop in the middle can be corrected accordingly:
while (!win) {
System.out.println("Guess a number between 1 and 10: ");
try {
guess = input.nextInt();
numberOfTries++;
if (guess == numberToGuess) {
win = true;
System.out.println("YOU GOT IT!");
System.out.println("It took you " + numberOfTries + " tires.");
} else if (guess < 1 || guess > 10) {
throw new BadGuessException();
}
} catch (InputMismatchException e) {
input.nextLine();
}
}
As for creating a custom exception class, you already did that. It's written a bit messy way, cleaning it up (removing unnecessary stuff) it becomes:
public class BadGuessException extends Exception {
private static final String message = "Sorry, that was an invalid guess!";
public BadGuessException() {
super(message);
}
}
UPDATE
I fixed another bug in your code: if you enter non-integer input, a InputMismatchException will be thrown. Repeatedly. Forever.
This is because the input.nextInt() doesn't consume the input if it's not valid. So the invalid input stays there, and input.nextInt() will keep failing, putting your program in an infinite loop.
To fix that, you must consume the bad input somehow, for example by reading the line:
} catch (InputMismatchException e) {
input.nextLine();
}
I think what you want is if they make a guess and it is incorrect, that your loop should run again, right? In that case, you should adjust your loop, as I've shown below. Also, where you are catching the InputMismatchException, you are swallowing the exception without printing it or handling it: This is VERY BAD PRACTICE. I've updated this too for you.
while (!win)
{
System.out.println("Guess a number between 1 and 10: ");
try
{
guess = input.nextInt();
numberOfTries++;
win=true;
if (guess == numberToGuess)
{
win = true;
System.out.println("YOU GOT IT!");
System.out.println("It took you " + numberOfTries + " tires.");
}
else
{
throw new BadGuessException();
}
}
catch(InputMismatchException e)
{
System.out.println("Please input a number betwee 1 and 10!");
}
catch(BadGuessException ex) {
System.out.println("Sorry, you guessed the wrong number!");
}
}
You never catch the BadGuessException so it will be thrown out of the while loop and program will exit. You must catch the exception inside the loop if you want to continue.
I agree with janos comment that this is not a good use of exceptions. Guessing wrong is part of the normal game flow, no?
But doing it for the practice, I'd for example pull all logic inside the loop into a new private method, let it throw this exception, and catch it in the loop. You can catch multiple exceptions in a row like this.
while (!win) {
try {
win = makeGuess();
} catch (InputMismatchException e) {
e.getMessage();
} catch (BadGuessException e) {
System.out.println("Wrong guess");
}
}
private boolean makeGuess() throws BadGuessException, InputMismatchException {
...
}
I have an error in a console program I'm making, in which I can't seem to handle an error.
If a user enters an incorrect input type (such as an float where an int goes), they are reprimanded, and the program functions (even though the program shuts down, it does it my way):
while(!scanner.hasNextLong()){
System.out.println("You entered something bad.. Why do you hurt me?");
System.out.println("*Calcumatastic dies, and I hope you feel remorseful*");
try {
Thread.sleep(4000);
} catch (InterruptedException f) {
f.printStackTrace();
}
System.exit(0);
}
If a user enters, for example, a zero as a variable that cannot equal zero (due to division of zero), the user is reprimanded, and life still goes on, and the program still functions:
while (b == 0) {
System.out.println("Did you even read the instructions?? You cannot divide by zero!");
System.out.println();
System.out.println("Second Integer: ");
b = scanner.nextLong();
}
However, if a user attempts to divide by zero, THEN enters an incorrect input type, the program crashes. What am I doing wrong? I've tried entering a try/catch- while loop as I did in other instances, but it doesn't seem to do the trick:
System.out.println("Second Integer: ");
while(!scanner.hasNextLong()){
System.out.println("You entered something bad.. Why do you hurt me?");
System.out.println("*Calcumatastic dies, and I hope you feel remorseful*");
try {
Thread.sleep(4000);
} catch (InterruptedException f) {
f.printStackTrace();
}
System.exit(0);
}
b = scanner.nextLong();
while (b == 0) {
System.out.println("Did you even read the instructions?? You cannot divide by zero!");
System.out.println();
System.out.println("Second Integer: ");
b = scanner.nextLong();
}
Your issue is that your input validation appears to be consecutive. That is, you check for invalid input and then you check for zero values. You probably want to do both every time there is input.
You probably want to check for all error cases in a single loop. Something like:
System.out.println("Second Integer: ");
// a loop wrapping your other validation checks
while(scanner.hasNext()){ // while there is input:
while(!scanner.hasNextLong()){ // check for non-long input
System.out.println("You entered something bad.. Why do you hurt me?");
System.out.println("*Calcumatastic dies, and I hope you feel remorseful*");
try {
Thread.sleep(4000);
} catch (InterruptedException f) {
f.printStackTrace();
}
System.exit(0);
}
b = scanner.nextLong();
while (b == 0) { // check for non-zero input
System.out.println("Did you even read the instructions?? You cannot divide by zero!");
System.out.println();
System.out.println("Second Integer: ");
b = scanner.nextLong();
}
}
If you try to perform a division by zero, an java.lang.ArithmeticException is thrown and when you try to read a long and user enters something that can't be parsed, InputMismatchException is thrown (possibly what you call a "crash").
Error is occurring because you are using b = scanner.nextLong(); when user enters 0 without checking if user entered a valid long value.
Here is your code adjusted:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
long b = 0;
do {
System.out.println("Second Integer: ");
b = readLong(scanner);
if (b == 0) {
System.out.println("Did you even read the instructions?? You cannot divide by zero!");
System.out.println();
}
} while (b == 0);
}
private static long readLong(Scanner scanner) {
if (!scanner.hasNextLong()) {
System.out.println("You entered something bad.. Why do you hurt me?");
System.out.println("*Calcumatastic dies, and I hope you feel remorseful*");
try {
Thread.sleep(4000);
} catch (InterruptedException f) {
f.printStackTrace();
}
System.exit(0);
}
return scanner.nextLong();
}
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.
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);
}
}