0

Getting this error when I try to have the user reinput a number.

while(guess != num) {
    System.out.println("Guess a number between 1 and 10.");
    try{
        guess = scan.nextInt();
    }catch(Exception e) {
        System.out.println("Enter a valid number.");
        guess = scan.nextInt();
    }
}

Error shows up at the next iteration of guess=scan.nextInt();

Input/Output:

Guess a number between 1 and 10.
d
Enter a valid number.
Exception in thread "main" java.util.InputMismatchException
    at java.base/java.util.Scanner.throwFor(Scanner.java:939)
    at java.base/java.util.Scanner.next(Scanner.java:1594)
    at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
    at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
    at HiLo.main(HiLo.java:19)

I am just relearning Java, any help is appreciated.

  • What do you enter, what do you expect to happen, and why? – JB Nizet Oct 10 '19 at 22:45
  • 1
    What error do you have? Please add your inputs and outputs – Villat Oct 10 '19 at 22:46
  • Maybe use 'e.printStackTrace()' inside the catch block to see what is the real exception. Also you might be facing the problem with the scanner where nextInt doesn't read the new line character – itwasntme Oct 10 '19 at 22:47
  • in your `catch` block, try removing `guess = scan.nextInt()` altogether – you only need to prompt for that once, which you are already doing in the `try` block – Kaan Oct 10 '19 at 22:56

2 Answers2

0

So, your catch statement technically handles the exception, but it still throws the original exception if you don't input a number (the scan line inside the try { ). You have to instead call scan.next(); in your catch statement. Java scanners are weird like that.

while(guess != num) {
         System.out.println("Guess a number between 1 and 10.");
         try{
            guess = scan.nextInt();
         }catch(Exception e) {
            System.out.println("Enter a valid number.");
            scan.next();
         }
      }

That should work.

Vortexian
  • 26
  • 5
  • hey that works but it goes to the next iteration in the while loop, but I want to have the user input their guess before that happens. – Ravi Shanker Gowda Oct 10 '19 at 22:51
  • @RaviShankerGowda In that case, just add a `guess = scan.nextInt();` after the `scan.next();` :) – Vortexian Oct 10 '19 at 22:52
  • And the user inputs 'a' character again, what now? New try-catch inside the existing? – itwasntme Oct 10 '19 at 22:54
  • @itwasntme could probably just put a while loop? Not entirely sure why a user would see that message and reenter a non-numeric character... – Vortexian Oct 10 '19 at 22:56
  • @Vortexian At the beginning user saw 'Guess a number between 1 and 10.' and entered 'd', then he sees 'Enter a valid number', so why not try to enter non-numeric val again? – itwasntme Oct 10 '19 at 23:01
  • @itwasntme The code clearly states that you should enter a number, not a non-numeric character; if we're assuming this program user is really dumb, or can't read, then you should probably loop until your input is valid, otherwise the single message should be enough. – Vortexian Oct 10 '19 at 23:05
  • the nexInt works after next, but its true that user can just enter same char again, anyway to reloop until right input type is made? – Ravi Shanker Gowda Oct 10 '19 at 23:07
  • @RaviShankerGowda I guess, yeah; I don't know how to best do it but I would personally just have a second while loop in your catch. – Vortexian Oct 10 '19 at 23:14
-1

The InputMismatchException is raised by the method nextInt of a Scanner instance after it reads any character which is not the integer. The maximum and minimum size of integer variable (int) in Java also must be taken under consideration.

The question is a bit unclear, but from the given code and sample user input I'm guessing that the goal to make user re-enter a numerical value until the required number is typed while informing user about the wrong input type.

Here's the way it could be achieved:

public class NumberGuessing {
    public static void main(String[] args) {
        int guess = -1;
        int num = 9;
        Scanner scan = new Scanner(System.in);
        while (true) {
            System.out.println("Guess a number between 1 and 10.");
            String enteredValue = scan.next();
            while(!validNumber(enteredValue)) {
                System.out.println("Enter a valid number.");
                enteredValue = scan.next();
            }
            guess = Integer.parseInt(enteredValue);
            if (guess == num) {
                System.out.println("That's right! The hidden number was: " + num);
                break;
            }
        }
    }
    private static boolean validNumber(String s) {
        try{
            int num = Integer.parseInt(s);
            return num >= 1 && num <= 10; //change this to `return true;` if range check is not needed
        }catch(NumberFormatException e) {
            return false;
        }
    }
}

The reason it uses the method next() of a Scanner instance is that the nextInt reads only the first string it sees without reading the new line character. So when looping with the nextInt inside, the next iteration would try to read new line character which would also result in InputMismatchException.

It's better to read whole line with next() from a console and later parse it aligning the input to user needs.

Edit2: If the range check is not needed you could just go with regex check:

while (guess != num) {
    System.out.println("Guess a number between 1 and 10.");
    String enteredValue = scan.next();
        while (!enteredValue.matches("-?\\d+")) {
        System.out.println("Enter a valid number.");
        enteredValue = scan.next();
    }
    guess = Integer.parseInt(enteredValue);
}

It allows the leading '0' in numbers which in some cases might not be valid number, if you want to avoid leading '0' change the matches method to .matches("-?(0|[1-9]\\d*)").

itwasntme
  • 1,442
  • 4
  • 21
  • 28