1

I was running a simple Calculator app to learn Java's exception handling. I've set two exceptions to be handled: InputMismatchException and ArithmeticException for division by zero.

ArithmeticException gets handled and the do-while loop continues. But after catching the InputMismatchException, the execution terminates rather than continuing the loop.

Code:

do {
  result = 0;
  System.out.println("Enter the expression to calculate: (eg: 4 + 5) \n");
  try {
    num1 = input.nextInt();
    op = input.next().charAt(0);
    num2 = input.nextInt();
    result = a.Calc(num1, op, num2);             //Calc function to calculate
    System.out.println("= " + result);
  } catch (InputMismatchException e) {
     System.err.println("Please space out the expression");
  } catch (ArithmeticException e) {
     System.err.println("Cannot divide by zero");
  }
  System.out.println("Do you want to try again? (Y to retry)");
  OP = input.next().charAt(0);
} while (OP == 'Y' || OP == 'y');

Output:

Enter the expression to calculate: (eg: 4 + 5)
4 / 0
Cannot divide by zero                  //Exception handled
Do you want to try again? (Y to retry)
Y                                      //Do-while continues

Enter the question to calculate: (eg: 4 + 5)
4+5
Please space out the expression        //Exception handled
Do you want to try again? (Y to retry) //Rest of the code is executed
                                       //But the execution also terminates

Expected: Do-while to continue after InputMismatchException

Is this the correct way of doing this?

  • 2
    your do-while continues just fine, otherwise you wouldn't see "Do you want..." question. I'm guessing you're reading character from `input` which is not 'Y' or 'y'. Print it, or set a breakpoint and see what's in `OP` after `input.nextLine().charAt(0)` – uaraven Aug 09 '19 at 17:50
  • @pydude No, the execution itself stops after the InputMismatchException. There's no waiting for input – Sameer Siddiqui Aug 10 '19 at 10:38

1 Answers1

3

InputMismatchException is caused by the call to nextInt(), because the next token is 4+5.

The token is not consumed by the failed call.

Which means that OP = input.next().charAt(0) sets OP = '4', something that should be very apparent if you debugged the code. See What is a debugger and how can it help me diagnose problems? and How to debug small programs.

You need to discard the failed token(s), e.g. by calling nextLine() in the catch clause:

} catch (InputMismatchException e) {
    System.err.println("Please space out the expression");
    input.nextLine(); // Discard input(s)
} ...
Andreas
  • 154,647
  • 11
  • 152
  • 247
  • Yeah, this worked for my currently written code. Thank you. But is this the proper way of taking an expression input or is there a better approach? – Sameer Siddiqui Aug 10 '19 at 10:37
  • @SameerSiddiqui It is one very rigid way to do it. Another way is to read the entire line, then give that to an **expression parser** to get an expression tree, also known as an [abstract syntax tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) (AST), but that's probably beyond your current skill level. – Andreas Aug 10 '19 at 10:57