Come posso impedire a uno scanner di lanciare eccezioni quando viene inserito il tipo sbagliato?

StackOverflow https://stackoverflow.com/questions/2496239

Domanda

Ecco un codice di esempio:

import java.util.Scanner;
class In
{
    public static void main (String[]arg) 
    {
    Scanner in = new Scanner (System.in) ;
    System.out.println ("how many are invading?") ;
    int a = in.nextInt() ; 
    System.out.println (a) ; 
    } 
}

Se eseguo il programma e lo do un int piace 4, allora va tutto bene.

D'altra parte, se rispondo too many Non ride della mia battuta divertente. Invece ottengo questo (come previsto):

Exception in thread "main" java.util.InputMismatchException
    at java.util.Scanner.throwFor(Scanner.java:819)
    at java.util.Scanner.next(Scanner.java:1431)
    at java.util.Scanner.nextInt(Scanner.java:2040)
    at java.util.Scanner.nextInt(Scanner.java:2000)
    at In.main(In.java:9)

C'è un modo per fargli ignorare le voci che non sono INTS o report con "Quanti sono invasori?" Mi piacerebbe sapere come fare entrambi.

È stato utile?

Soluzione

Puoi usare uno dei tanti hasNext* metodi che Scanner ha per pre-convalida.

    if (in.hasNextInt()) {
        int a = in.nextInt() ; 
        System.out.println(a);
    } else {
        System.out.println("Sorry, couldn't understand you!");
    }

Questo impedisce InputMismatchException dall'essere anche lanciato, perché ti assicuri sempre che questo VOLERE abbina prima di leggerlo.


java.util.Scanner API

  • boolean hasNextInt(): Ritorna true Se il token successivo nell'input di questo scanner può essere interpretato come un valore INT nel radix predefinito usando il nextInt() metodo. Lo scanner non avanza oltre alcun input.

  • String nextLine(): Fa avanzare questo scanner oltre la linea corrente e restituisce l'input che è stato saltato.

Tieni presente le sezioni in grassetto. hasNextInt() non avanza oltre nessun input. Se ritorna true, puoi far avanzare lo scanner chiamando nextInt(), che non lancerà un InputMismatchException.

Se ritorna false, quindi devi saltare oltre la "spazzatura". Il modo più semplice per farlo è solo chiamando nextLine(), probabilmente due volte ma almeno una volta.

Perché potresti dover fare nextLine() Due volte è il seguente: Supponiamo che questo sia l'input inserito:

42[enter]
too many![enter]
0[enter]

Diciamo che lo scanner è all'inizio di quell'input.

  • hasNextInt() è vero, nextInt() ritorna 42; Lo scanner è ora a appena prima il primo [enter].
  • hasNextInt() è falso, nextLine() restituisce una stringa vuota, un secondo nextLine() ritorna "too many!"; Lo scanner è ora a subito dopo il secondo [enter].
  • hasNextInt() è vero, nextInt() ritorna 0; Lo scanner è ora a appena prima il terzo [enter].

Ecco un esempio di mettere insieme alcune di queste cose. Puoi sperimentarlo per studiare come Scanner lavori.

        Scanner in = new Scanner (System.in) ;
        System.out.println("Age?");
        while (!in.hasNextInt()) {
            in.next(); // What happens if you use nextLine() instead?
        }
        int age = in.nextInt();
        in.nextLine(); // What happens if you remove this statement?

        System.out.println("Name?");
        String name = in.nextLine();

        System.out.format("[%s] is %d years old", name, age);

Diciamo che l'input è:

He is probably close to 100 now...[enter]
Elvis, of course[enter]

Quindi l'ultima riga dell'uscita è:

[Elvis, of course] is 100 years old

Altri suggerimenti

In generale, non mi piace molto usare la stessa domanda di biblioteca sia per la lettura che per l'analisi. Le biblioteche linguistiche sembrano essere molto inflessibili e spesso non possono essere piegate alla tua volontà.

Il primo passo che estrae i dati da System.in non dovrebbe essere in grado di fallire, quindi fallo leggerlo come una stringa in una variabile, quindi converti quella variabile di stringa in un int. Se la conversione fallisce, ottimi: eseguire il tuo errore e continuare.

Quando avvolgi il tuo flusso con qualcosa che può lanciare un'eccezione, diventa un po 'confuso ciò che lo stato l'intero casino lascia il tuo flusso.

È sempre un vantaggio avere L'applicazione lancia un errore quando si verifica un errore contrario a modi per mantenere sta accadendo.

Un'alternativa è quella di avvolgere il codice all'interno di a try {...} catch {...} blocco per InputMismatchException. Potresti anche voler avvolgere il codice all'interno di un while Loop per avere il Scanner Continua a suggerire fino a quando non viene soddisfatta una condizione specifica.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top