1

If I type in letter for the first Scanner statement i get "error!!" and "enter a number" but cannot input another number.I am a beginner and do not know whether an input statement can be used within a catch statement

 import java.util.InputMismatchException;
 import java.util.Scanner;
 public class excep {
 public static void main(String args[]){
     int n;
     Scanner input=new Scanner(System.in);
     try{
         System.out.println("ENTER A NUMBER: ");
          n=input.nextInt();
     }
     catch(InputMismatchException e){
         System.out.println("ERROR!!! \nENTER A NUMBER :");
         n=input.nextInt();
     }
 }
 }
JSON C11
  • 11,272
  • 7
  • 78
  • 65
  • are you getting any error? – Akash Shinde Apr 09 '15 at 06:00
  • here is something about it. http://stackoverflow.com/questions/12702076/java-try-catch-with-inputmismatchexception-creates-infinite-loop – newuserua_ext Apr 09 '15 at 06:00
  • yeah.... Exception in thread "main" java.util.InputMismatchException at java.util.Scanner.throwFor(Unknown Source) at java.util.Scanner.next(Unknown Source) at java.util.Scanner.nextInt(Unknown Source) at java.util.Scanner.nextInt(Unknown Source) at excep.rajath.main(rajath.java:14) –  Apr 09 '15 at 06:02
  • You need to [account for linefeed](http://stackoverflow.com/a/4708312/2398375) – Vince Apr 09 '15 at 06:07
  • @VinceEmigh no, actually, you don't. If the input contains only valid integers, then it doesn't matter what kind of whitespace is between them--space, newline, tab, whatever. (We get a lot of questions here where someone has tried `nextLine()` without consuming the previous end-of-line. But in general, if you are using only `nextInt()` you don't need to worry about it. The linefeed is not the problem here.) – ajb Apr 09 '15 at 06:09
  • @ajb I was assuming he the input wasn't valid integers, since he's catching an `InputMismatchException`, which is the cause for requesting input again. When testing it (on my phone's ide - AIDE) the `nextInt()` call in the catch statement didn't register correctly until I called `nextLine()` after. Not gonna lie, I don't work with `Scanner` much anymore (haven't in a while; rusty), so I could be mistaken. (which is why this is a comment). If I am, I'm truely sorry, but it's still some interesting info to read about! :) – Vince Apr 09 '15 at 06:19
  • 1
    @VinceEmigh you could have used `next()` instead of `nextLine()`; `next()` stops at any whitespace, whether a newline or not. That's why I don't believe you need to account for linefeed. I'd use `nextLine()` anyway, though. – ajb Apr 09 '15 at 06:24

4 Answers4

4

You must have to eat or remove characters from the buffer before you restart input. For the sake of simplicity, your code should look alike :

while(true) {
  Scanner input=new Scanner(System.in);
  try {
     System.out.println("ENTER A NUMBER: ");
     n=input.nextInt();
     break;
 }catch(InputMismatchException e) {
   System.out.println("ERROR!!! \nENTER A NUMBER :");
   input.next(); // eat some chars
 }
}
KV Prajapati
  • 93,659
  • 19
  • 148
  • 186
3

The biggest problem with your approach is that if nextInt() fails because the user did not enter a valid integer, the scanner does not advance. The scanner has a pointer that points to the next character to read from the input. When you use nextInt(), if the next "token" is an integer, the scanner will advance the pointer past the integer. But if it isn't an integer, an exception is thrown--and the pointer stays in the same place as before. So when you catch the exception, then call nextInt(), the scanner tries to read the same invalid integer that it just tried to read last time.

To skip over the bad integer, you can say input.next() to skip over one token, or input.nextLine() to skip over the entire remainder of the input line, before trying to read another integer. (Both of these return String results, but you can discard the result since it's not important to you).

However, this is not really a good way to use try/catch. If the user is having a bad day and enters another invalid integer, the scanner will throw an exception, and it will not be caught, since you are not in the try when the second exception is thrown. catch doesn't loop back and catch it again. The best idiom for this is a loop:

boolean validIntegerEntered = false;
System.out.println("ENTER A NUMBER: ");
while (!validIntegerEntered) {
    try {
        n=input.nextInt();
        validIntegerEntered = true;  // will not get here if nextInt()
                                     // throws an exception
    }
    catch (InputMismatchException e) {
        input.nextLine();            // let the scanner skip over the bad input
        System.out.println("ERROR!!! \nENTER A NUMBER :");
        // don't call nextInt() here; loop back, and nextInt() will be called
        // in the try statement
    }
}
ajb
  • 31,309
  • 3
  • 58
  • 84
2

Syntactically, Yes you can but you shouldn't use it. Why?

input.nextInt(); can throw InputMismatchException or NoSuchElementException or IllegalStateException if the scanner is closed.

If any of those exceptions occur within the catch block, you are not handling them. You should probably look at how to implement a retry catch

Community
  • 1
  • 1
TheLostMind
  • 35,966
  • 12
  • 68
  • 104
-1

You are using the input.nextInt(), means it can only accepts int values.If you want to enter string values then better to use input.nextine(). In your code in catch block you are using again input.nextInt() but scanner has already wrong input in it that why it throw the exception.If you want to take input inside catch block then try the below code:

     catch(InputMismatchException e){        
         System.out.println("ERROR!!! \nENTER A NUMBER :");
         Scanner input1=new Scanner(System.in);
         n=input1.nextInt();
         System.out.println("Inside catch:"+n);
     }
GAgarwal
  • 122
  • 4