Domanda

Sto usando il seguente codice:

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.");
    }
}

Tuttavia, se entro in un 'w' che mi dirà "Hai inserito dati non validi. Riprova." e poi si andrà in un ciclo infinito che mostra il testo "Specificare un numero intero compreso tra 0 e 5:.. È stato immesso un input non valido Prova di nuovo"

Perché succede questo? Non è il programma dovrebbe attendere che l'utente di input e premere invio ogni volta che si raggiunge l'istruzione:

if (in.hasNextInt())
È stato utile?

Soluzione

Nel tuo ultimo blocco else, è necessario cancellare l'input non valido 'w' o altro dallo scanner. È possibile farlo chiamando next() sullo scanner e ignorando il suo valore di ritorno di buttare via quel input non valido, come segue:

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

Altri suggerimenti

Il problema era che non hai avanzare il Scanner passato l'ingresso problematico. Da hasNextInt() documentazione :

  

Restituisce true se il prossimo token di ingresso di questo scanner può essere interpretato come un valore int nei radix predefinite utilizzando il metodo nextInt(). Lo scanner non avanzare oltre qualsiasi ingresso.

Questo è vero per tutti i metodi hasNextXXX(): tornano true o false, senza avanzare l'Scanner

.

Ecco un frammento per illustrare il problema:

    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!
        }
    }

Troverete che questo programma andrà in un ciclo infinito, chiedendo ripetutamente int, please!.

Se si rimuove il commento la dichiarazione sc.next(), allora farà la Scanner oltrepassare il token che non riesce hasNextInt(). Il programma dovrebbe quindi stampare:

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

Il fatto che un controllo hasNextXXX() fallito non salta l'ingresso è intenzionale: esso consente di eseguire ulteriori controlli su quel segno, se necessario. Ecco un esempio per illustrare:

    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());
        }
    }

Se si esegue questo programma, il risultato sarà il seguente:

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

Questa affermazione di Ben S. sulla chiamata non bloccante è falsa:

  

Inoltre, hasNextInt () non blocca. E 'l'assegno non-blocking per vedere se un futuro prossimo bando potrebbe ricevere input senza bloccare.

... anche se riconosco che la documentazione può essere facilmente frainteso per dare a questo parere, e il nome stesso implica che deve essere utilizzato per questo scopo. La citazione in questione, con particolare attenzione ha aggiunto:

  

Il prossimo () e hasNext () metodi e loro metodi compagno primitiva di tipo (come nextInt () e hasNextInt ()) prima saltare qualsiasi voce che corrisponde al modello delimitatore, e quindi tentare di restituire il token successivo. Sia hasNext e successivi metodi si bloccano in attesa di ulteriore ingresso. se un metodo hasNext blocchi non è connesso con se la sua metodo successivo associato bloccherà.

Si tratta di un punto sottile, per essere sicuri. O dicendo "Sia il e hasNext prossimi metodi", o "Entrambi hasNext () e next ()" avrebbe implicato che i metodi compagno sarebbe agire in modo diverso. Ma visto che sono conformi alla stessa convenzione di denominazione (e la documentazione, ovviamente), è ragionevole aspettarsi che agiscono allo stesso, e hasNext () dice chiaramente che può bloccare.

Nota Meta: questo dovrebbe probabilmente essere un commento al post non corretta, ma sembra che come nuovo utente posso postare solo questa risposta (o modificare il wiki che sembra essere preferito per le modifiche sytlistic, non quelli di sostanza) .

variabili Flag sono troppo soggetto a errori da usare. Utilizzare il controllo ciclo esplicito con i commenti, invece. Inoltre, hasNextInt() fa non bloccare. E 'il controllo non-blocking per vedere se un futuro next chiamata potrebbe ricevere input senza bloccare. Se si desidera bloccare, utilizzare il nextInt() metodo.

// 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);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top