Come posso impedire a uno scanner di lanciare eccezioni quando viene inserito il tipo sbagliato?
-
21-09-2019 - |
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.
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()
: Ritornatrue
Se il token successivo nell'input di questo scanner può essere interpretato come un valore INT nel radix predefinito usando ilnextInt()
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()
ritorna42
; Lo scanner è ora a appena prima il primo[enter]
.hasNextInt()
è falso,nextLine()
restituisce una stringa vuota, un secondonextLine()
ritorna"too many!"
; Lo scanner è ora a subito dopo il secondo[enter]
.hasNextInt()
è vero,nextInt()
ritorna0
; 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.