Frage

Ich bin mit dem folgenden Code:

while (invalidInput)
{
    // ask the user to specify a number to update the times by
    System.out.print("Specify an integer between 0 and 5: ");

    if (in.hasNextInt())
    {
        // get the update value
        updateValue = in.nextInt();

        // check to see if it was within range
        if (updateValue >= 0 && updateValue <= 5) 
        { 
            invalidInput = false; 
        } 
        else 
        {
            System.out.println("You have not entered a number between 0 and 5. Try again.");
        }
    } else
    {
        System.out.println("You have entered an invalid input. Try again.");
    }
}

Allerdings, wenn ich geben Sie eine ‚w‘ es wird mir sagen, „Sie haben eine ungültige Eingabe eingegeben. Versuchen Sie es erneut.“ und dann wird es in eine Endlosschleife zeigt den Text „Geben Sie eine ganze Zahl zwischen 0 und 5:.. Sie haben eine ungültige Eingabe eingegeben Versuchen Sie es erneut“

Warum ist das passiert? Ist das nicht das Programm sollte für den Benutzer zur Eingabe warten, und drücken Sie die Eingabetaste jedes Mal, wenn die Anweisung erreicht:

if (in.hasNextInt())
War es hilfreich?

Lösung

In Ihrem letzten else Block, müssen Sie die ‚w‘ oder andere ungültige Eingabe von dem Scanner löschen. Sie können dies tun, indem next() auf dem Scanner aufrufen und den Rückgabewert ignorieren wegzuwerfen, dass ungültige Eingabe wie folgt:

else
{
      System.out.println("You have entered an invalid input. Try again.");
      in.next();
}

Andere Tipps

Das Problem war, dass man nicht die Scanner vorbei an dem problematischen Eingang weiter vorangeschritten. Von hasNextInt() Dokumentation :

  

Returns true wenn das nächste Token in diesem Eingang des Scanners kann als int Wert im Standard radix interpretiert werden, um die nextInt() Methode. Der Scanner nicht vorab über jede Eingabe.

Dies gilt für alle hasNextXXX() Methoden. Sie zurückkehren true oder false, ohne die Scanner vorrückenden

Hier ist ein Ausschnitt, das Problem zu veranschaulichen:

    String input = "1 2 3 oops 4 5 6";
    Scanner sc = new Scanner(input);
    while (sc.hasNext()) {
        if (sc.hasNextInt()) {
            int num = sc.nextInt();
            System.out.println("Got " + num);
        } else {
            System.out.println("int, please!");
            //sc.next(); // uncomment to fix!
        }
    }

Sie werden feststellen, dass dieses Programm in eine Endlosschleife gehen, fragt int, please! wiederholt.

Wenn Sie die sc.next() Anweisung Kommentar-, dann wird es die Scanner gehen vorbei an den Token machen, die hasNextInt() ausfällt. Das Programm würde dann drucken:

Got 1
Got 2
Got 3
int, please!
Got 4
Got 5
Got 6

Die Tatsache, dass eine gescheiterte hasNextXXX() Prüfung kann die Eingabe nicht überspringen ist beabsichtigt: es Sie auf diesem Token zusätzliche Prüfungen durchführen kann, wenn nötig. Hier ist ein Beispiel zur Veranschaulichung:

    String input = " 1 true foo 2 false bar 3 ";
    Scanner sc = new Scanner(input);
    while (sc.hasNext()) {
        if (sc.hasNextInt()) {
            System.out.println("(int) " + sc.nextInt());
        } else if (sc.hasNextBoolean()) {
            System.out.println("(boolean) " + sc.nextBoolean());
        } else {
            System.out.println(sc.next());
        }
    }

Wenn Sie dieses Programm ausführen, gibt er folgende:

(int) 1
(boolean) true
foo
(int) 2
(boolean) false
bar
(int) 3

Diese Aussage von Ben S. über den nicht-blockierenden Aufruf ist falsch:

  

Auch hasNextInt () nicht blockiert. Es ist die nicht-blockierende Überprüfung, ob ein zukünftiger nächster Anruf Eingang bekommen kann, ohne zu blockieren.

... obwohl ich erkenne, dass die Dokumentation kann leicht falsch verstanden werden, diese Stellungnahme zu geben, und der Name selbst bedeutet es für diesen Zweck verwendet werden soll. Die entsprechende Quote mit Betonung hinzugefügt:

  

Der nächste () und hasNext () Methoden und ihre primitive artigen Begleiter Methoden (wie nextInt () und hasNextInt ()) überspringen zunächst jede Eingabe, die das Trennzeichen Muster übereinstimmt, und dann versuchen, das nächste Token zurückzukehren. Sowohl hasNext und nächstes Verfahren können für die weiteren Eingabeblock wartet. Ob ein hasNext Methode blockiert hat keine Verbindung, ob nicht auf die zugehörige nächste Methode blockiert.

Es ist ein subtiler Punkt, um sicher zu sein. Entweder sagen: „Beide die hasNext und nächste Methoden“ oder „Beiden hasNext () und next ()“ würde angedeutet haben, dass die Begleiter Methoden würden anders handeln. Aber da sie auf die gleiche Namenskonvention (und die Dokumentation, natürlich) entsprechen, ist es vernünftig zu erwarten, sie das gleiche handeln, und hasNext () klar sagt, dass es blockieren kann.

Meta Hinweis: Dies sollte wohl ein Kommentar zu dem falschen Posten sein, aber es scheint, dass ich als neuen Benutzer ich nur diese Antwort veröffentlichen kann (oder bearbeiten das Wiki, die für sytlistic Änderungen bevorzugt zu sein scheint, nicht die der Substanz) .

Flag-Variablen sind zu fehleranfällig zu verwenden. Verwenden Sie explizite Regelung mit Kommentaren statt. Auch hasNextInt() tut blockieren Sie nicht. Es ist die nicht-blockierende Überprüfung, ob eine Zukunft next Anruf konnte Eingabe erhalten, ohne zu blockieren. Wenn Sie blockieren möchten, verwenden Sie die nextInt() Verfahren.

// Scanner that will read the integer
final Scanner in = new Scanner(System.in);
int inputInt;
do {  // Loop until we have correct input
    System.out.print("Specify an integer between 0 and 5: ");
    try {
        inputInt = in.nextInt(); // Blocks for user input
        if (inputInt >= 0 && inputInt <= 5)  { 
            break;    // Got valid input, stop looping
        } else {
            System.out.println("You have not entered a number between 0 and 5. Try again.");
            continue; // restart loop, wrong number
         }
    } catch (final InputMismatchException e) {
        System.out.println("You have entered an invalid input. Try again.");
        in.next();    // discard non-int input
        continue;     // restart loop, didn't get an integer input
    }
} while (true);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top