javaexceptionswitch-statementdo-whileinputmismatchexception

Stop infinite Loop when handling invalid user input - Java


I'm fairly new to programming and I'm having trouble with my program continuously looping when I try to handle a InputMisMatch exception.

I have a menu which takes in user input and then uses a switch statement to deal with the input. I am trying to make my program handle two exceptions. First is making sure that the input is actually an integer and secondly make sure the integer is within the range for the menu. I used the NextInt() method inside a try block. Inside the try block is the switch statement which uses the default case to deal with the input not being in range

However the catch block for when the user types in an input other than an integer keeps looping over and over. It seems I have not updated the user input inside the loop somewhere but I am confused as to where to update it.

For now, I'm not concerned with what is in the switch cases (although I want to implement the same looping feature inside of them as well), It's just the logic for the outer loop.

Here's my code:

Any guidance would be much appreciated. Thanks!

    public class Main {
    
    // set up scanner for user input
    public static Scanner keyboard = new Scanner(System.in);

    public static void main(String[] args) {
        // welcome message
        welcome();

        //declare user choice variables
        int menuSelection;
        int discSelection;

        boolean isInputValid = true ;

        do { // keep looping until user input is valid
            try {
                /*
                    We can expect an error from user input
                    1. Input is not an integer
                    2. Input is not in range
                 */

                isInputValid = true;
                displayMainMenu();
                menuSelection = keyboard.nextInt();
                System.out.println(); //print new line

                //Menu Logic
                switch (menuSelection) {
                    case 0: { // Exit Application
                        break;
                    }
                    case 1: { // Search
                        searchDiscMenu(); //Display the search menu
                        discSelection = keyboard.nextInt(); // get user choice
                        if (discSelection == 1) {
                            System.out.println("Disc.Music.searchMusic()");
                        } else if (discSelection == 2) {
                            System.out.println("Disc.Game.searchGame()");
                        }
                        break;
                    }
                    case 2: { // Add
                        addDiscMenu(); //Display add menu
                        discSelection = keyboard.nextInt(); // get user choice
                        if (discSelection == 1) {
                            System.out.println("Disc.Music.addMusic()");
                        } else if (discSelection == 2) {
                            System.out.println("Disc.Game.addGame();");
                        }
                        break;
                    }
                    case 3: { // Remove
                        removeDiscMenu(); //Display remove menu
                        discSelection = keyboard.nextInt(); // get user choice
                        if (discSelection == 1) {
                            System.out.println("Disc.Music.removeMusic();");
                        } else if (discSelection == 2) {
                            System.out.println("Disc.Game.removeGame();");
                        }
                        break;
                    }
                    case 4: { // View
                        viewDiscMenu(); //Display view menu
                        discSelection = keyboard.nextInt(); // get user choice
                        if (discSelection == 1) {
                            System.out.println("Disc.Music.viewMusic();");
                        } else if (discSelection == 2) {
                            System.out.println("Disc.Music.viewMusic();");
                        }
                        break;
                    }
                    case 5: { // Sort
                        sortDiscMenu(); //Display sort menu
                        discSelection = keyboard.nextInt(); // get user choice
                        if (discSelection == 1) {
                            System.out.println("Disc.Music.viewMusic();");
                        } else if (discSelection == 2) {
                            System.out.println("Disc.Music.viewMusic();");
                        }
                        break;
                    }
                    case 6: { // Write
                        writeDiscMenu(); //Display write menu
                        discSelection = keyboard.nextInt(); // get user choice
                        if (discSelection == 1) {
                            System.out.println("Disc.Music.viewMusic();");
                        } else if (discSelection == 2) {
                            System.out.println("Disc.Game.writeGameFile();");
                        }
                        break;
                    }
                    case 7: { // Read
                        readDiscMenu(); //Display read menu
                        discSelection = keyboard.nextInt(); // get user choice
                        if (discSelection == 1) {
                            System.out.println("Disc.Music.readMusicFile();");
                        } else if (discSelection == 2) {
                            System.out.println("Disc.Game.readGameFile();");
                        }
                        break;
                    }
                    default: { // Handle exception
                        isInputValid = false;
                        System.out.println("Error: Selection Not In Range"); // If the input is an int but not in range
                        break;
                    }
                }
            } catch (InputMismatchException e) { // Handles user typing in a char, double etc. instead of int
                isInputValid = false;
                System.out.println("Error: Unrecognised Input");
            }
        } while (!isInputValid);

        // Exit application safely
        System.out.println("Finished"); // temporary message

    }

Solution

  • This can happen since the nextInt() doesn't consume the new line character inserted in the buffer when pressed enter to type something in the console.

    To overcome this you can add keyboard.nextLine() to the catch block so you can consume that new line character inserted in the buffer and clear it to the next input.

    As others said you should wrap your input hadling in a method since you have louds of nextInt that won't be catched by your InputMismatchException. Said method should call the nextInt() catch the exception if needed and clear the buffer for new line characteres with the nextLine() if not returns the input by the user.

    That way you're guarantee that you will always catching that error.