In the first try and catch it works exactly how I need it to however in the other two they don't and I am not sure why.
First One: It asks for a difficulty 1 - 3 if it isn't 1,2, or 3 it loops till they enter 1,2 or 3 and if they put anything but an int it will say "Invalid Difficulty" and ask for them to input again.
Issue: None (that I know of)
try {
System.out.println("What would you like the difficulty to be?");
System.out.println("Easy = 1, Medium = 2, Hard = 3");
difficulty = userInput.nextInt();
while((difficulty < 1 || difficulty > 3)){
System.out.println("Invalid Difficulty. \n");
difficulty = userInput.nextInt();
}
} catch(InputMismatchException exception) {
System.out.println("Invalid Difficulty.\n");
difficulty = selctDifficulty();
}
Second One: Should do the same as above just without the loop to male sure it falls between 2 numbers.
Issue: If they don't enter an int it says Invalid amount then crashes with
Exception in thread "main" java.util.InputMismatchException
try {
System.out.println("How many pitchers would you like to buy?");
amountOfPitchers = userInput.nextInt();
} catch(InputMismatchException exception) {
System.out.println("Invalid Amount.\n");
amountOfPitchers = userInput.nextInt();
}
Third One: Should work exactly as the first.
Issue: If I enter a string it crashes with
Exception in thread "main" java.util.InputMismatchException
try {
System.out.println("How much do you want to charge per cup?");
System.out.println("Between $0.05 and $2.00");
pricePerCup = userInput.nextDouble();
while((pricePerCup < 0.05 || pricePerCup > 2.00)){
System.out.println("Invalid Amount. \n");
pricePerCup = userInput.nextDouble();
}
} catch(InputMismatchException exception) {
System.out.println("Invalid Amount.\n");
pricePerCup = userInput.nextDouble();
}
Your error line tells you clearly what and where the error is:
Exception in thread "main" java.util.InputMismatchException
Something in your catch clause for your second and third example is giving you error, but not the first one. Do you see why?
Upon simple inspection, for your second and third try and catch, after an exception has occured due to invalid input, your are still attempting to process input using userInput.nextInt() and userInput.nextDouble(). The exception this causes will not be caught and is therefore causing problems.
You need to do userInput.next() in your catch in order to move to the next input
Your first appears to be recursive in the catch block, your third isn't...
System.out.println("Invalid Amount: " + userInput.next()); // <-- read the non-double.
// pricePerCup = userInput.nextDouble();
pricePerCup = selectPricePerCup();
Cause you do pricePerCup = userInput.nextDouble(); in catch?
If you catch it why you try to process input once again when it is not valid input?
Read about exceptions and what catch block really does.
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
}
}
This is my first Java program. The assignment is to create a program as follows:
Develop a Java program that works as follows:
1). When the program is started, it displays a message welcoming the player: "Welcome to Game Guru!"
2). Then it creates a secret random number between 1 and 20;
3), Then it displays a message saying: "Guess my magic number [1-20]: "
4). Read and check the number entered by the player.
If is not a number, the program displays a message saying: "Should enter a number". then go back to step 3)
If the number is out of range, the program displays a message saying: "Number out of range". Then go back to step 3)
If the number is smaller than the secret number, the program displays a message saying: "Number too small". Then go back to step 3)
If the number is greater than the secret number, the program displays a message saying: "Number too large". Then go back to step 3)
If the number is the same as the secret number, the program displays a message saying: "You got it!". Then go to step 5)
5). The program displays a message saying: "Want more games?"
6). Read the player's answer. If the answer is "yes", then to step 1); If the answer is "no", then go to step 7)
7). The program displays message "Thanks for playing the game. Goobye".
I have gotten it working completely EXCEPT when entering anything other than an INT it gives an exception. I tried researching this myself and found the Try/Catch but it doesn't seem to be working for me. My instructor wont help me...despite the fact that he hasn't actually taught any of this...
Here's my code:
public static void main(String[] args)
{
// TODO Auto-generated method stub
String more;
do
{
System.out.println("Welcome to Game Guru!");
int number = 1 + (int)(Math.random() * 20);
int guess = 0;
Scanner input = new Scanner(System.in);
try
{
System.out.println("Guess my magic number [1-20]: ");
guess = input.nextInt();
}
catch (Exception e)
{
System.out.println("Should enter an integer");
}
while (guess != number)
{
if (guess > 20 || guess < 1)
{
System.out.println("Number out of range");
System.out.println("Guess my magic number [1-20]: ");
guess = input.nextInt();
}
else if (guess < number)
{
System.out.println("Number too small");
System.out.println("Guess my magic number [1-20]: ");
guess = input.nextInt();
}
else if (guess > number)
{
System.out.println("Number too large");
System.out.println("Guess my magic number [1-20]: ");
guess = input.nextInt();
}
}
if (guess == number)
{
System.out.println("You got it!");
}
System.out.println("Want more games? Please enter Y or N.");
more = input.next();
} while (more.equals("y") || more.equals("Y"));
System.out.println("Thanks for playing the game. Goodbye");
}
}
Here's the console:
Welcome to Game Guru!
Guess my magic number [1-20]:
a
Should enter an integer
Number out of range
Exception in thread "main" java.util.InputMismatchException
at java.base/java.util.Scanner.throwFor(Unknown Source)
at java.base/java.util.Scanner.next(Unknown Source)
at java.base/java.util.Scanner.nextInt(Unknown Source)
at java.base/java.util.Scanner.nextInt(Unknown Source)
Guess my magic number [1-20]:
at Game.main(Game.java:46)
I really appreciate any insight into this. I'm at my wits end...I should be paying Google my tuition.
So, starting with...
try
{
System.out.println("Guess my magic number [1-20]: ");
guess = input.nextInt();
}
catch (Exception e)
{
System.out.println("Should enter an integer");
}
Basically, if an exception occurs, the Scanner still contains non-numerical data in it's buffer, this means that if you then try and read the buffer again, doing something like...
guess = input.nextInt();
You will get the same exception again.
A general solution is to call input.nextLine() to clear the buffer before attempting to read new data from it. Personally, I'd use nextLine for all the inputs and Integer.parseInt to parse those elements which you want as int values, but that's me.
Since you have to ask the user for input each time they need to make a guess, you could simplify your solution by using a do-while loop instead (you have to enter the loop at least once any way), this way you could get the input, verify the value (as an int) and perform your required logic on it, all within a single basic loop...
Scanner input = new Scanner(System.in);
String more = "N";
do {
System.out.println("Welcome to Game Guru!");
int number = 1 + (int) (Math.random() * 20);
int guess = 0;
do {
try {
System.out.println("Guess my magic number [1-20]: ");
String text = input.nextLine();
guess = Integer.parseInt(text);
if (guess > 20 || guess < 1) {
System.out.println("Number out of range");
} else if (guess < number) {
System.out.println("Number too small");
} else if (guess > number) {
System.out.println("Number too large");
}
} catch (NumberFormatException e) {
System.out.println("Should enter an integer");
}
} while (guess != number);
System.out.println("You got it!");
System.out.println("Want more games? Please enter Y or N.");
more = input.nextLine();
} while (more.equalsIgnoreCase("y"));
In the try, you are giving the code you want to execute (fine). In the except statement, you are correctly printing out the error too (great).
Unfortunately, you didn't fix it!
It probably makes sense to put your try/catch in a while loop that repeats until you get valid input. That way, once it works, you move on to the rest of your logic which is dependent on getting valid input from the user in the try/catch.
You're asking to enter an int, if the user enter another value as a String or Float you will get an exception.
Add another try{} catch{} block to verify if it is an Integer otherwise cast it
What happens in your code is that it catches that exception in the first try/catch, prints System.out.println("Should enter an integer"); and then proceeds to the rest of the do block. You need to continue after printing that message.
However, you'll encounter more bugs in that code as you continue testing, this is just to answer your question about that exception.
The purpose of your try/ catch is to tell the user that the number they selected is not an integer. The program is not supposed to continue if you enter something other than an integer, as it says in step 4- The first if statement is used to verify that the number is an integer.
Instead, you are using a try/ catch, which also stops the program, but a little differently.try/catch block
The block of code in the try statement prompts the user to enter a number 1-20. If it is not, it throws the exception because the number entered is not an integer. It prints the message " Should enter an integer", and prints out the errors that should tell the user what is wrong. It is telling you there is an error in the Main class of your program, and where the problem is located. The purpose of the print statement " Should enter an integer" was to prompt the user to enter an integer the next time the program runs, so the program can then run correctly.
In your case, the if statement would make more sense to use. Again, the only point of this block of code is to verify the user has entered an integer.
I have copied the exact same code from another program. Whenever inputting deliberate incorrect results the InputMismatchException still occurs and the program crashes.
import java.util.*;
public class Runner{
public static void main (String args[]){
Scanner sc = new Scanner(System.in);
sc.useDelimiter("\n");
Fixture f = new Fixture();
boolean inputValid = false;
int choice = 0;
do{
do {
System.out.println("\f\t\tFootball Database");
System.out.println("A utility to help make footballing events easier to manage.");
System.out.println("");
System.out.println("\t> Press 1 to manage players ");
System.out.println("\t> Press 2 to manage teams");
System.out.println("\t> Press 3 to manage coaches");
System.out.println("\t> Press 4 to manage fixtures");
System.out.println("\t> Press 5 to save database to file");
System.out.println("\t> Press 6 to load database from file");
System.out.println("\t> Press 7 to terminate program");
System.out.println("");
System.out.println("");
System.out.println("©Thomas Camilleri 2017");
try{
choice = sc.nextInt();
inputValid = true;
}catch(InputMismatchException e){
System.out.println("Invalid input");
inputValid = false;
sc.nextInt();
sc.nextInt();
}
}while(inputValid == false);
Here is the salient part of your code:
try {
choice = sc.nextInt(); // NOT HERE
inputValid = true;
} catch(InputMismatchException e){
System.out.println("Invalid input");
inputValid = false;
sc.nextInt(); // HERE
sc.nextInt();
}
If you look at the stacktrace that you got, and look at the line numbers, you will see that the line in your code where the exception happens is the one I have tagged with // HERE.
(Compile and run the original program and look at the stacktrace to see what I mean. Compare the line numbers in the stack trace with the source code.)
As you can see, that line is NOT in the try { ... } block. It is in the exception handler block.
What has happened is that you have caught the exception that was thrown at the line tagged // NOT HERE, and then you have called sc.nextInt() again (at // HERE). The second call has simply attempted to read the same input characters again.
The behavior of the nextInt method is as follows:
get characters sufficient to form a token
attempt to convert the entire token into an integer (using base-10 integer syntax)
if the conversion succeeds, return the converted integer
if the conversion fails, put all of the characters back and then throw an exception.
I strongly encourage you to carefully read the javadocs for the Scanner class so that you understand what the methods you are using actually do.
So ... as you see ... if you just call nextInt() after a failed nextInt() call, you just get the same failure repeated.
The reason that second exception is not caught is that it has not been thrown within the try { ... } block.
Solution: Instead of calling nextInt() in the handler, you should call a method that is going to just discard the rubbish. In this case, the most sensible thing to do is to throw away everything up to the next end-of-line.
Hint #1: the nextLine() gets everything up to the next end-of-line. Read the javadocs for that method too.
Hint #2: if you understand what I said, you will know where to put your modification.
Try like:
choice = Integer.parseInt(sc.nextLine());
and your program will like this:
try (Scanner sc = new Scanner(System.in)) {
sc.useDelimiter("\n");
// Fixture f = new Fixture();
boolean inputValid = false;
int choice = 0;
// removed outer do..while(); loop
do {
System.out.println("\f\t\tFootball Database");
System.out.println("A utility to help make footballing events easier to manage.");
System.out.println("");
System.out.println("\t> Press 1 to manage players ");
System.out.println("\t> Press 2 to manage teams");
System.out.println("\t> Press 3 to manage coaches");
System.out.println("\t> Press 4 to manage fixtures");
System.out.println("\t> Press 5 to save database to file");
System.out.println("\t> Press 6 to load database from file");
System.out.println("\t> Press 7 to terminate program");
System.out.println("");
System.out.print("Enter your choice : ");
try{
// Always use nextLine() if you mix String and basic Datatype
choice = Integer.parseInt(sc.nextLine());
inputValid = true;
}catch(NumberFormatException e){
System.out.println("Invalid input");
inputValid = false;
// Removed unnecessary two sc.nextInput() lines
}
}while(inputValid == false);
System.out.println("choice is : " + choice);
}
Can someone tell me how to prevent this:
"Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:909)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextInt(Scanner.java:2160)
at java.util.Scanner.nextInt(Scanner.java:2119)
at JeffSky.main(JeffSky.java:25)"
when the user inputs a letter for an int.
Basically I am trying to find out how to keep the program running even though a wrong data type has been entered. Just like you can do an if statement to notify the user it is not allowed if they input an int outside a given range e.g from 1-10.
for(int x=1; x<=3;x++) {
int guess;
System.out.print("Your chosen trap is: ");
do{
guess=sean.nextInt();
if(guess>=1 && guess<=6){
//do nothing if is a valid number i.e a trap between 1 and 6.
}
else {
System.out.print("Has to be between 1-6. Try again: ");
}
}
while(guess<1 || guess>6);
Cheers
InputMismatchException from nextInt means the input is not an int. You can catch it.
This will loop until the input is a number between 1 and 6:
do {
try {
guess = sean.nextInt();
if (guess >= 1 && guess <= 6) break;
} catch (InputMismatchException e) {
} finally {
sean.nextLine();
}
System.out.print("Input must be a number between 1 and 6: ");
} while (true);
Side note: calling nextInt will also orphan a new line character, so nextLine advances past it.
This error is usually thrown when you use methods like scanner.nextInt();. If you want to avoid those, use something like String input = scanner.next(), then check input to see if it can be represented as an Integer.
I'm a beginner with Java and was attempting to catch the exception 'InputMismatchException'. Below is my code, I hope it is easy to read, apologies in advance if it's not formatted well. It builds fine and executes, but if I input a character for example the 'catch' doesn't function and the error comes up;
"Exception in thread "main" java.util.InputMismatchException"
I believe everything else in the code works fine including the 'try', and I don't have anything going in the catch other than a System.out.print command.
import java.util.*; // imports
public class w4q1
{
public static void main(String[] args)
{
Scanner user_input = new Scanner( System.in ); // declaring Scanner util
System.out.print("Please enter an integer: \n"); // Asks for input
int d = user_input.nextInt();
while (d > 0 || d < 0) // start of while loop, in the event of anything other than zero entered
{
try {
if (d < 0) // if statements
{
System.out.print("The integer " + d + " is negative\n");
break;
}
else if (d > 0)
{
System.out.print("The integer " + d + " is positive\n");
break;
}
else
{
System.out.print("You have not entered an integer\n");
break;
}
}
catch (InputMismatchException e) // Error message for letters/characters and decimals
{
System.out.print("You have entered an incorrect value, please restart the program\n");
}
}
if (d == 0)
{
System.out.print("A zero has been entered\n");
}
}
}
If you are still receiving an InputMismatchException even though you have a try-catch block, then the exception must be coming from somewhere outside of your try-catch block.
Look at what else outside the try-catch block can throw an InputMismatchException and put a try-catch block around that statement, or expand your existing try-catch block to include that statement.
If indeed the exception is not getting caught, then the resulting stack trace should show you the actual line of code which threw the exception. Looking at the code, I'm going to guess that this is where the exception occurs:
user_input.nextInt();
I would recommend you look at the stack trace and see if you can confirm this.
Put a try-catch block around this code
int d = user_input.nextInt();
and by so doing ,you also need to change the current code a little bit to make it OK. Good Luck !