4

In the catch block, I'm trying to correct for user bad-input issues. When testing it, if I use the "break" keyword, it doesn't jump to the initial question. If I use "continue", it loops infinitely. "Sc.next();" doesn't seem to resolve it either.

Here's the relevant part of the code.

public class ComputerAge {
    private static int age;
    private static int year;
    private static int month;
    private static int date;
    private static Calendar birthdate;

    static Scanner sc = new Scanner(System.in);

    public static void main(String[] args) {
        System.out.print("Enter the numeral representing your birth month: ");
        do {
            try {
                month = sc.nextInt();
            } catch (InputMismatchException ime){
                System.out.println("Your respone must be a whole number");
                break;
            }
        } while (!sc.hasNextInt());
Chris Forrence
  • 10,042
  • 11
  • 48
  • 64
  • `break` breaks out of the loop, and continues executing instructions coming *after* the loop. Why do you use an exception, and not the result of `hasNextInt()`, to check whether the user entered an int? – JB Nizet Mar 08 '14 at 22:23
  • Thanks for clearing up the "break" keyword. I thought it would simply jump back into the next outer shell. – user3397080 Mar 08 '14 at 22:55

5 Answers5

3

The problem with your approach is that when you call sc.nextInt() and it throws an exception, Scanner does not advance its reading position. You need to advance the reading pointer by calling sc.next() inside the catch block instead of the break:

do {
    try {
        month = sc.nextInt();
    } catch (InputMismatchException ime){
        System.out.println("Your respone must be a whole number");
        sc.next(); // This will advance the reading position
    }
} while (!sc.hasNextInt());
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
3

In order to fix the problem, we should identify what we want to accomplish at the end.
We want the month to be a numeral month, that is number > 0.

Thus:

  • If a user fill a correct number month will be filled.
  • Otherwise, Exception will be thrown and month will stay as '0'.

Conclusion: We want our program will keep running when month is equals 0.

The solution is pretty simple:

While condition should be:

while (month == 0);

And you should change break to sc.next().

Orel Eraki
  • 11,940
  • 3
  • 28
  • 36
  • Thank you, so very much, Orel! When I'm finished with this I'm going to keep practicing these loops until I get it! – user3397080 Mar 08 '14 at 22:44
2

I think you should use an infinite loop, and when the input is correct (no exception thrown), use break to finish the loop:

public static void main(String args[])
{
    System.out.print("Enter the numeral representing your birth month: ");
    do {
        try {
            int month = sc.nextInt();
            break;
        } catch (InputMismatchException ime) {
            System.out.println("Your respone must be a whole number");
            sc.nextLine();
        }
    } while (true);
}

Also, you will have to use sc.nextLine() in the catch block because when you enter some input and press Enter, a new-line character is added, and nextInt() doesn't read it. You have to use nextLine() to consume that character. For further information about this issue you could read this.

Christian Tapia
  • 33,620
  • 7
  • 56
  • 73
2

First of all, you have to avoid use try/catch in iteratives sentences in order to improve perfomance.

You can recode for the break to work in this way (keep in mind that de do-while will execute at least one time, so if your scanner retrieve null value, you will have nullPointer)

    try {
       while (sc != null && !sc.hasNextInt()) {
            month = sc.nextInt();
        } 
    } catch (InputMismatchException ime){
            System.out.println("Your respone must be a whole number");
    }
Francisco Hernandez
  • 2,378
  • 14
  • 18
1

Make sure you can get the integer first, and use regular expressions. Don't use exceptions if possible to enforce code logic.

int month;
boolean correct = false;
while (!correct && sc.hasNextLine())
{
    String line = sc.nextLine();
    if (!line.matches("^[0-9]+$"))
    {
        System.out.println("Your response must be a whole number");
        correct = false;
    }
    else
    {
        month = Integer.parseInt(line);
        correct = true;
    }
}
djhaskin987
  • 9,741
  • 4
  • 50
  • 86
  • 1
    Why use a regexp when scanner.hasNextInt() does that for you? – JB Nizet Mar 08 '14 at 22:47
  • I'll try to avoid it. I had the impression that this was what the professor wanted since catching errors was the subject of his lecture but if it's bad coding, I'll avoid it if I can. – user3397080 Mar 08 '14 at 22:48