1

My code below occur this error when I typed letter instead of number.

import java.util.Scanner;

public class ExceptionExample {
    public static void main(String[] args) {

        Scanner number = new Scanner(System.in);

        int x = 1;
        do {
            try {
                int n1, n2;
                System.out.println("Enter the firs num");
                n1 = number.nextInt();

                System.out.println("Enter the second num");
                n2 = number.nextInt();

                int sum = n1 / n2;
                System.out.println(sum);

                x = 2;
            } catch (Exception e) {
                System.out.println("You can not do that\n");
            }
        } while (x == 1);

    }
}

When I entered the letter, I expected to get just one line of "You can not do that" but it shows me infinite loop like this.

Enter the firs num
You can not do that

Enter the firs num
You can not do that

Enter the firs num
You can not do that
.
.
.

if anyone knows why does this happen?

Pshemo
  • 122,468
  • 25
  • 185
  • 269
MINJU KANG
  • 11
  • 1
  • 2
    There is still a new line character in the `Scanner`s buffer. When using something like `nextInt`, you need to also ensure you use `nextLine` to remove the new line character from the buffer – MadProgrammer Jan 14 '18 at 21:40
  • Please [format your code](https://meta.stackexchange.com/questions/22186/how-do-i-format-my-code-blocks) correctly. – Micheal O'Dwyer Jan 14 '18 at 21:42
  • @MadProgrammer Not exactly new line character, it is entire token which was cached by scanner (we can read it in catch section even with `next()` method and get rid of it). – Pshemo Jan 14 '18 at 21:42
  • @Dukeling Not in my experience - as this seems to be the focus (and common solution) for solving this kind of problem – MadProgrammer Jan 14 '18 at 21:47
  • @Pshemo A new line character would remain in the buffer after the `int` was read, yes, you can use `next` as well, but since we're focused on keyboard input – MadProgrammer Jan 14 '18 at 21:50
  • 1
    @MadProgrammer Let me rephrase: I don't believe this has anything to do with newline characters - the default delimiter for Scanner is whitespace, so a newline character wouldn't cause any problems with multiple calls to nextInt (although I wouldn't argue if you say using nextLine instead of next to get rid of the invalid input might make more sense, since the rest of the line is likely garbage as well). – Bernhard Barker Jan 14 '18 at 21:51
  • @Dukeling Then can you explain the issue? Every time I've ever seen this problem, it's related to a dangling new line character - actually, it's because the contents of the buffer haven't been read from the buffer due to the failure for the expression to be validated (as an `int` or a correct regular expression match to be found), so yes, a new line character is incorrect – MadProgrammer Jan 14 '18 at 21:55
  • @MadProgrammer New line characters are not causing any problem for `nextInt()` method. We can let scanner read `"1\n\n\n\n2"` and after invoking `nextInt()` twice we will get `1` and `2`. By default one or more whitespaces (which includes line separators) are treated as delimiter. Problem with line separator appears when we are using `nextLine` after other `next...()` methods, because `nextLine` will return empty string. But that is not the case here. – Pshemo Jan 14 '18 at 21:57
  • @Pshemo Yes, the issue is due to the fact the `nextInt` does not find a valid match and fails, leaving the text in the buffer - this is why I generally avoid it, read the buffer (using `next` or `nextLine`) and do the parsing myself – MadProgrammer Jan 14 '18 at 21:58
  • "Then can you explain the issue?" as already mentioned in duplicate "`When a scanner throws an InputMismatchException, the scanner will not pass the token that caused the exception, so that it may be retrieved or skipped via some other method.`". In other words Scanner caches invalid token internally to let us get its value via other (better) methods. For instance when we asked user for number and instead of writing integer we are getting long we can still use `nextLong` after `nextInt` to get provided number. – Pshemo Jan 14 '18 at 21:59
  • @MadProgrammer "Yes, the issue is due to the fact the nextInt does not find a valid match and fails" true, but that is because token doesn't represent `int`, not because there is line separator after it. In other words when data looks like `"123\n"` scanner doesn't have problem with it, but when it looks like `"a\n"` `nextInt()` throws exception because of `"a"` not because of `"\n"` after it (line separator is treated as delimiter, so it is used only to determine end of token, it doesn't cause problem for `nextInt()`). Scanner will cache that `"a\n"`, not only `"\n"`. – Pshemo Jan 14 '18 at 22:09
  • 1
    @Pshemo Yes, which is the conclusion I've now come to, nice if some one could have simply said that in the first place, rather then just saying "you are wrong" - yes, I was in my assumption, just nice to be told why ;) - although the overriding solution is to use either `next` to `nextLine` to clear the buffer before the `nextLine` statement - at least within then the `catch` block – MadProgrammer Jan 14 '18 at 22:19
  • @MichealO'Dwyer will do! thanks micheal! – MINJU KANG Jan 15 '18 at 10:01
  • phew! I still have far away to go! thanks guy I'll study harder ! – MINJU KANG Jan 15 '18 at 10:02
  • @MINJUKANG No worries! – Micheal O'Dwyer Jan 15 '18 at 17:15

0 Answers0