-1

I'm not sure how to set it up, but my method has a user input a number between a minimum and maximum, although I have no idea how to handle the NumberFormatException with a try-catch block. Are there any suggestions in regards to how this can be fixed?

static int promptForInt(String prompt, int min, int max){
        System.out.println(prompt);
        String input = in.readLine();
        int parsedInt = Integer.parseInt(input);
        while(!(parsedInt > min && parsedInt < max)){
            System.out.println("Your input is invalid. " + prompt);
            input = in.readLine();
            parsedInt = Integer.parseInt(input);
        }
        return parsedInt;
    }
xenteros
  • 15,586
  • 12
  • 56
  • 91
Vokundiiv
  • 9
  • 1

2 Answers2

0
static int promptForInt(String prompt, int min, int max){
    System.out.println(prompt);
    String input = in.readLine();
    int parsedInt;
    boolean exceptionThrown = false;
    do {
        try {
            parsedInt = Integer.parseInt(input);
        } catch(NumberFormatException e) {
            exceptionThrown = true;
        }
        if (exceptionThrown || (!(parsedInt > min && parsedInt < max)) {
            System.out.println("Your input is invalid. " + prompt);
            input = in.readLine();
            parsedInt = Integer.parseInt(input);
        } else {
            return parsedInt;
        }
    } while(true)
}

From my post about NumberFormatException:

Ad. 4.

Finally we come to the place in which we agree, that we can't avoid situations when it's user typing "abc" as a numeric string. Why? Because he can. In a lucky case, it's because he's a tester or simply a geek. In a bad case it's the attacker.

What can I do now? Well, Java gives us try-catch you can do the following:

try {
    i = Integer.parseInt(myString);
} catch (NumberFormatException e) {
    e.printStackTrace();
    //somehow workout the issue with an improper input. It's up to your business logic.
}

Exceptions

In Java Exceptions are used for marking unexpected situations. For example parsing non-numeric String to a number (NumberFormatException) or calling a method on a null reference (NullPointerException). You can catch them in many ways.

try{
    //some code
} catch (NumberFormatException e1) {
    e.printStackTrace()     //very important - handles the Exception but prints the information!
} catch (NullPointerException e2) {
    e.printStackTrace();
}

or using the fact, that they all extend Exception:

try {
    //somecode
} catch (Exception e) {
    e.printStackTrace;
};

or since Java 7:

try {
    //somecode
} catch (NullPointerException | NumberFormatException e) {
    e.printStackTrace;
};
Community
  • 1
  • 1
xenteros
  • 15,586
  • 12
  • 56
  • 91
-1

Exceptions can be easier to deal with if you think of them as the method "Trying to do something, but it couldn't because of X". X is the exception.

The below code could be one way you modify your code to handle the exception:

static int promptForInt(String prompt, int min, int max) {
    Integer parsedInt = null; // use an Integer so null can be used to mean an invalid value
    while (parsedInt == null) {
        System.out.println(prompt);
        String input = in.readLine();
        int temp;
        try {
            temp = Integer.parseInt(input);
        } catch(NumberFormatException e) {
            System.out.print(input+" is not a number.  ");
            continue;
        }
        if (temp < min || temp > max) {
            System.out.print("Your number must be between "+min+" and "+max+" (inclusive).  ");
        } else {
            parsedInt = temp;
        }
    }
    return parsedInt;
}

Some things you should notice: Firstly, you have not defined in. You could do that like so:

BufferedReader in = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));

If you do that, you'll soon see that you have another Exception to deal with: this can throw UnsupportedEncodingException, and also readLine can throw IOException.

Your method must return a valid integer or it will not exit (you really should supply the user some means of exiting the loop without entering a valid number). Since that's not going to be possible if, for instance, you couldn't read anything from System.in your method needs a reasonable way of telling the caller: "I tried to get an int from the user, except I was stopped by X".

You may actually end up doing something more like:

static int promptForInt(String prompt, int min, int max) throws UserInputException {
    BufferedReader in;
    try {
        in = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
    } catch(UnsupportedEncodingException unsupported) {
        // create a new exception and supply the cause as an inner exception
        throw new UserInputException("Could not open a reader for System.in", unsupported);
    }
    Integer parsedInt = null; // use an Integer so null can be used to mean an invalid value
    while (parsedInt == null) {
        System.out.println(prompt);
        String input;
        try {
            input = in.readLine();
        } catch (IOException ioException) {
            throw new UserInputException("Could not read a line", ioException);
        }
        if (input.length() == 0) {
            throw new UserInputException("User aborted input");
        }
        int temp;
        try {
            temp = Integer.parseInt(input);
        } catch(NumberFormatException e) {
            System.out.print(input+" is not a number.  ");
            continue;
        }
        if (temp < min || temp > max) {
            System.out.print("Your number must be between "+min+" and "+max+" (inclusive).  ");
        } else {
            parsedInt = temp;
        }
    }
    return parsedInt;
}
Tibrogargan
  • 4,508
  • 3
  • 19
  • 38