-2

I have copied the exact same code from another program. Whenever inputting deliberate incorrect results the InputMismatchException still occurs and the program crashes.

import java.util.*;
    public class Runner{
    public static void main (String args[]){
    Scanner sc = new Scanner(System.in);
    sc.useDelimiter("\n");
    Fixture f = new Fixture();
    boolean inputValid = false;
    int choice = 0;
    do{
        do {
            System.out.println("\f\t\tFootball Database");
            System.out.println("A utility to help make footballing events easier to manage.");
            System.out.println("");
            System.out.println("\t> Press 1 to manage players ");
            System.out.println("\t> Press 2 to manage teams");
            System.out.println("\t> Press 3 to manage coaches");
            System.out.println("\t> Press 4 to manage fixtures");
            System.out.println("\t> Press 5 to save database to file");
            System.out.println("\t> Press 6 to load database from file");
            System.out.println("\t> Press 7 to terminate program");
            System.out.println("");
            System.out.println("");
            System.out.println("©Thomas Camilleri 2017");
            try{
                choice = sc.nextInt();
                inputValid = true;
            }catch(InputMismatchException e){
                System.out.println("Invalid input");
                inputValid = false;
                sc.nextInt();
                sc.nextInt();
            }
        }while(inputValid == false);
  • 1
    Please read [mcve] and enhance your question accordingly. Describe what you expect to happen and what actually happens with the necessary details. – GhostCat Feb 04 '18 at 12:46
  • I ran the program and inputted letters instead of integers to check if the catch was working. The program showed me the InputMismatchException error anyways, regardless of my try-catch block. –  Feb 04 '18 at 12:55
  • https://stackoverflow.com/q/3572160/ – bcsb1001 Feb 04 '18 at 12:57
  • I'm not getting an infinite loop –  Feb 04 '18 at 13:00
  • Read the answer to that question. The problem is that, if an `InputMismatchException` is thrown, the token is not consumed. – bcsb1001 Feb 04 '18 at 13:06
  • If you can explain in simpler terms it would be helpful, my english is a bit limited when it comes to java. –  Feb 04 '18 at 13:11

2 Answers2

1

Here is the salient part of your code:

        try {
            choice = sc.nextInt();   // NOT HERE
            inputValid = true;
        } catch(InputMismatchException e){
            System.out.println("Invalid input");
            inputValid = false;
            sc.nextInt();            // HERE
            sc.nextInt();
        }

If you look at the stacktrace that you got, and look at the line numbers, you will see that the line in your code where the exception happens is the one I have tagged with // HERE.

(Compile and run the original program and look at the stacktrace to see what I mean. Compare the line numbers in the stack trace with the source code.)

As you can see, that line is NOT in the try { ... } block. It is in the exception handler block.

What has happened is that you have caught the exception that was thrown at the line tagged // NOT HERE, and then you have called sc.nextInt() again (at // HERE). The second call has simply attempted to read the same input characters again.

The behavior of the nextInt method is as follows:

  • get characters sufficient to form a token
  • attempt to convert the entire token into an integer (using base-10 integer syntax)
  • if the conversion succeeds, return the converted integer
  • if the conversion fails, put all of the characters back and then throw an exception.

I strongly encourage you to carefully read the javadocs for the Scanner class so that you understand what the methods you are using actually do.

So ... as you see ... if you just call nextInt() after a failed nextInt() call, you just get the same failure repeated.

The reason that second exception is not caught is that it has not been thrown within the try { ... } block.

Solution: Instead of calling nextInt() in the handler, you should call a method that is going to just discard the rubbish. In this case, the most sensible thing to do is to throw away everything up to the next end-of-line.

Hint #1: the nextLine() gets everything up to the next end-of-line. Read the javadocs for that method too.

Hint #2: if you understand what I said, you will know where to put your modification.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Thank you for this reply. I can say I've finally understood and got my program to work successfully. Thank you very much, this was explained excellently –  Feb 04 '18 at 13:44
-1

Try like:

choice = Integer.parseInt(sc.nextLine());

and your program will like this:

try (Scanner sc = new Scanner(System.in)) {

    sc.useDelimiter("\n");
//    Fixture f = new Fixture();
    boolean inputValid = false;
    int choice = 0;

//    removed outer do..while(); loop

    do {
        System.out.println("\f\t\tFootball Database");
        System.out.println("A utility to help make footballing events easier to manage.");
        System.out.println("");
        System.out.println("\t> Press 1 to manage players ");
        System.out.println("\t> Press 2 to manage teams");
        System.out.println("\t> Press 3 to manage coaches");
        System.out.println("\t> Press 4 to manage fixtures");
        System.out.println("\t> Press 5 to save database to file");
        System.out.println("\t> Press 6 to load database from file");
        System.out.println("\t> Press 7 to terminate program");
        System.out.println("");

        System.out.print("Enter your choice : ");
        try{
//    Always use nextLine() if you mix String and basic Datatype
            choice = Integer.parseInt(sc.nextLine());
            inputValid = true;
        }catch(NumberFormatException e){
            System.out.println("Invalid input");
            inputValid = false;
//    Removed unnecessary two sc.nextInput() lines
        }
    }while(inputValid == false);

    System.out.println("choice is : " + choice);
}
ArifMustafa
  • 4,617
  • 5
  • 40
  • 48
  • Got a different error in the console this time; java.lang.NumberFormatException: For input string: "a" –  Feb 04 '18 at 12:55
  • @ThomCamilleri I have just edited the answer, watch it. – ArifMustafa Feb 04 '18 at 12:57
  • Then i keep getting "invalid input", even when i input an integer. –  Feb 04 '18 at 13:10
  • @ThomCamilleri I have removed one outer do{...}while(); loop and you only concentrate to specially on 4 lines after input to choice variable, because this source is tested and if this is helpful learn [how to mark answer](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work). – ArifMustafa Feb 04 '18 at 13:15
  • This is a poor answer. You have not explained what the problem in his original code was. Instead, you have just given him an alternative version, which he has copy-and-pasted ... and not learned anything. – Stephen C Feb 04 '18 at 13:16
  • @StephenC I have just given the comment and now going to edit the answer. – ArifMustafa Feb 04 '18 at 13:17