MuchoG
MuchoG

Reputation: 55

Handling InputMismatchException in a While-Loop

So I have a while-loop where you have 3 options to choose from and you choose them by inserting a number on standard input using a scanner, my code is like this:

    int option;
    String request;
    Scanner input2 = new Scanner(System.in);
    System.out.println("Choose an option:\n" + "1-Get camera information\n" + "2-Submit Data\n"
         + "3-Exit");
    while(true){
        try {
            option = input2.nextInt();
            if (option == 1) {
                System.out.println("Camera name:");
                request = input2.nextLine();
                while (request.length() < 3 || request.length() > 15) {
                    System.out.println("Name has to be between 3 and 15 characters, insert a new one:");
                    request = input2.nextLine();
                }
                CamInfoRequest info_request = CamInfoRequest.newBuilder().setName(request).build();
                if (stub.camInfo(info_request).getReturn() != 0) {
                    System.out.println("Camera does not exist");
                } else {
                    System.out.println(stub.camInfo(info_request).getLatitude() + " " + stub.camInfo(info_request).getLongitude());
                }
            } else if (option == 2) {
                System.out.println("submit");
            } else if(option ==3){
                break;
            } else{
                System.out.println("Invalid option.");
            }
        }catch(InputMismatchException e){
            System.out.println("Invalid input");
        }
    }

So the way this is the code enters in an infinite loop when it catches the exception where it keeps printing "Invalid input", I tried using input2.next() at the catch but then he waits for another input I don't want, I can't use input2.close() either. What can I do?

Upvotes: 1

Views: 1183

Answers (2)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79065

I can't use input2.close() either.

You should never close the Scanner instance for System.in as it also closes the System.in.

I tried using input2.next() at the catch but then he waits for another input I don't want

Use Scanner::nextLine instead of Scanner::next, Scanner::nextInt etc. Check Scanner is skipping nextLine() after using next() or nextFoo()? to learn why.

Also, try to use do...while wherever you need to ask the user to enter the data again in case of an invalid entry.

Given below is a sample code incorporating these points:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        int option;
        boolean valid;
        Scanner input2 = new Scanner(System.in);
        do {
            valid = true;
            System.out.println("Choose an option:\n" + "1-Get camera information\n" + "2-Submit Data\n" + "3-Exit");
            try {
                option = Integer.parseInt(input2.nextLine());
                if (option < 1 || option > 3) {
                    throw new IllegalArgumentException();
                }
                // ...Place here the rest of code (which is based on the value of option)
            } catch (IllegalArgumentException e) {
                System.out.println("This is an invalid entry. Please try again.");
                valid = false;
            }
        } while (!valid);
    }
}

A sample run:

Choose an option:
1-Get camera information
2-Submit Data
3-Exit
abc
This is an invalid entry. Please try again.
Choose an option:
1-Get camera information
2-Submit Data
3-Exit
6
This is an invalid entry. Please try again.
Choose an option:
1-Get camera information
2-Submit Data
3-Exit
2

Feel free to comment in case of any further doubt/issue.

Upvotes: 1

Sandeep Lakdawala
Sandeep Lakdawala

Reputation: 492

Just Put the Scanner statement inside your try block

while (true) {
            try {
                Scanner input2 = new Scanner(System.in);
                option = input2.nextInt();
                if (option == 1) {

Upvotes: 0

Related Questions