javainputmismatchexception

Java - Try/Catch not moving past InputMismatchException


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.


Solution

  • 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"));