How do I ensure that Scanner hasNextInt() asks for

2020-02-12 21:53发布

问题:

New programmer here. This is probably a really basic question, but it's stumping me nevertheless.

What I'm trying to do is write a method that supplies only one integer input so I can use that input in my main program without having to mess around with non-integer inputs. However, even writing the method to do that in its own method seems to be problematic.

public static int goodInput () {
    Scanner input = new Scanner (System.in); //construct scanner
    boolean test = input.hasNextInt(); //set a sentinel value
    while (test == false) { //enter a loop until I actually get an integer
        System.out.println("Integers only please"); //tell user to give me an integer
        test = input.hasNextInt(); //get new input, see if it's an integer
    }
    int finalInput = input.nextInt(); //once i have an integer, set it to a variable
    input.close(); //closing scanner
    return finalInput; //return my integer so I don't have to mess around with hasNextInt over there
}

This seems to be broken in multiple levels, but I'm not really sure why.

If I enter an integer value like 0 or 1 when I'm first asked for input, it should skip the loop entirely. But, instead, it enters the loop, and prints "Integers only please". Even worse, it doesn't actually ask for input while I'm in there, and just prints that line repeatedly.

I understand the latter problem is probably due to token issues, but I'm not necessarily sure how to solve them; closing and then reopening the scanner gets Eclipse to bug me over "duplicate objects", simply assigning the old input to a garbage String variable that is never used tells me that "No line was found" at runtime, and I'm not experienced enough to think of other ways to get new input.

Even once that's solved, I need to find some way to avoid entering the loop in the case of having an integer. I don't really understand why integer inputs inter the loop to begin with, so I'm not sure how this would be possible.

Please help? Sorry if this is an old question; tried looking at past questions but none of them seem to have the same problem that I have.

回答1:

You were close: this works fine for me:

Scanner input = new Scanner(System.in); //construct scanner
while(!input.hasNextInt()) {
    input.next(); // next input is not an int, so consume it and move on
}
int finalInput = input.nextInt();
input.close(); //closing scanner
System.out.println("finalInput: " + finalInput);

By calling input.next() in your while loop, you consume the non-integer content and try again, and again, until the next input is an int.



回答2:

//while (test == false) {                         // Line #1
while (!test) { /* Better notation */             // Line #2
    System.out.println("Integers only please");   // Line #3
    test = input.hasNextInt();                    // Line #4
}                                                 // Line #5

The problem is that in line #4 above, input.hasNextInt() only tests if an integer is inputted, and does not ask for a new integer. If the user inputs something other than an integer, hasNextInt() returns false and you cannot ask for nextInt(), because then an InputMismatchException is thrown, since the Scanner is still expecting an integer.

You must use next() instead of nextInt():

while (!input.hasNextInt()) {
    input.next();
    // That will 'consume' the result, but doesn't use it.
}
int result = input.nextInt();
input.close();
return result;