0

When InputMismatchException is thrown I enter an infinite loop and I can not for the life of me figure out why. Basically the main goal of this program is to throw an exception for a negative number entered by the user and to make sure that the user actually enters an integer (not something like "r45"). Any help would be greatly appreciated. Thank you.

  import java.util.*;

  public class conversion{
  static Scanner in = new Scanner (System.in);
  static final double centimeters_per_inch = 2.54;
  static final int inches_per_foot = 12;

  public static void main (String [] args){
  int feet;
  int inches;
  int totalInches;
  double centimeters;
  boolean done = false;
  do{
    try
       {
       System.out.print("Enter feet: ");
       System.out.flush();
       feet = in.nextInt();
       System.out.println();
       System.out.print("Enter inches: ");
       System.out.flush();
       inches = in.nextInt();

       if (feet < 0 || inches < 0)
         throw new NonNegative();

       System.out.println();

       done = true;
       System.out.println("The numbers you entered are " + feet +" feet and " + inches+ " inches");
       totalInches = inches_per_foot * feet + inches;
       System.out.println();
       System.out.println("The total number of inches = " + totalInches);
       centimeters = totalInches * centimeters_per_inch;
       System.out.println("The number of centimeteres = " + centimeters); 
     }

     catch (NonNegative a){
       System.out.println(a.toString());   
     }
     catch(InputMismatchException e) {
       System.out.println("This is not a number");
     }
   }while(!done);
 }

}

Paul L
  • 459
  • 1
  • 4
  • 13
  • If the problem was with reading input, after you catch your exception, isn't your code just going to go back and try to read again, with (predictably) the same results? If not, please describe just what is happening in this "infinite loop". – Scott Hunter Oct 19 '13 at 22:40
  • This is very similar to http://stackoverflow.com/questions/19261374/exception-handling-catch-causes-while-loop-to-stop/19261467#19261467 – Brandon Oct 19 '13 at 23:12

2 Answers2

4

When an InputMismatchException occurs, the invalid input from Scanner is sent back through the while loop and the process is repeated ad infinitum. Invoke nextLine to consume the non-numeric input from the Scanner. This will prevent the unconsumed data from being sent back into the loop

System.out.println("This is not a number " + in.nextLine());
Reimeus
  • 152,723
  • 12
  • 195
  • 261
  • Thank you very much. It works just fine now.. Im not really sure what you mean by "comsume the invalid characters" but Ill look into it. Either way THANK YOU! – Paul L Oct 19 '13 at 22:48
  • the invalid characters are the non-numeric data that is entered from the `Scanner` which are the cause of the infinite loop... – Reimeus Oct 19 '13 at 23:05
  • 1
    Consider [accepting this answer](http://meta.stackexchange.com/a/65088/155831) is you found it helpful :) – Reimeus Oct 19 '13 at 23:10
-1

Having catch inside of a loop is usually an anti-pattern, for two reasons.

  1. You occasionally get weird behavior like this, and...
  2. Exceptions are slow compared to explicitly checking the data yourself.

So what you've got here:

do { 
  try {

  } catch () {
  }
} while ()

Is much more commonly written...

try {
  do {

  } while ();
} catch () {

}

Exceptions should be saved for cases that are exceptional; you probably shouldn't use them as functionality that will happen every time a method is called.

Dean J
  • 35,669
  • 13
  • 61
  • 92
  • This makes no sense. How slow is the exception, compared to user input? Some *million* times faster, I guess. Also, it is the Scanner that throws the exceptions, he only catches them and takes this a sopportunity to try again. – Ingo Oct 20 '13 at 01:06
  • Yeah, in this case, the user input is millions of times slower. I'm guessing this probably isn't the last program they'll write, so I'm commenting on a pretty common anti-pattern I see here. Put another way, I'd read Strings from the Scanner, validate they can be parsed as a number, then parse them to a number; no exceptions to worry about, as Exception should be saved for things that are really, actually exceptional. – Dean J Oct 20 '13 at 01:35