Comment puis-je garder un scanner de lancer des exceptions lorsque le mauvais type est entré?
-
21-09-2019 - |
Question
Voici quelques exemples de code:
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) ;
}
}
Si je lance le programme et lui donner un int
comme 4
, alors tout va bien.
Par contre, si je réponds too many
il ne se moque pas de ma blague drôle. Au lieu de cela, je reçois ce (comme prévu):
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)
Y at-il un moyen de faire ignorer les entrées qui ne sont pas ints ou re rapide avec « Combien envahissent? » Je voudrais savoir comment faire les deux.
La solution
Vous pouvez utiliser l'une des nombreuses méthodes de hasNext*
que Scanner
a pour pré-validation.
if (in.hasNextInt()) {
int a = in.nextInt() ;
System.out.println(a);
} else {
System.out.println("Sorry, couldn't understand you!");
}
Cela empêche InputMismatchException
de même être jeté, parce que vous faites toujours qu'il match avant que vous le lire.
java.util.Scanner API
-
boolean hasNextInt()
: retourtrue
si le prochain jeton dans l'entrée de ce scanner peut être interprété comme une valeur int dans la base par défaut en utilisant la méthodenextInt()
. Le scanner ne fait pas avancer passé toute entrée. -
String nextLine()
. Advances ce scanner passé la ligne actuelle et retourne l'entrée qui a été sauté
Gardez à l'esprit les sections en gras. hasNextInt()
ne fait pas avancer passé toute entrée. Si elle retourne true
, vous pouvez avancer le scanner en appelant nextInt()
, qui ne sera pas jeter un InputMismatchException
.
Si elle retourne false
, alors vous devez passer devant le « ordures ». La meilleure façon de le faire est tout simplement en appelant nextLine()
, probablement deux fois, mais au moins une fois.
Pourquoi vous devez faire nextLine()
est deux fois ce qui suit: supposons que ceci est l'entrée entré:
42[enter]
too many![enter]
0[enter]
Disons que le scanner est au début de cette entrée.
-
hasNextInt()
est vrai, revientnextInt()
42
; scanner est maintenant à juste avant la première[enter]
. -
hasNextInt()
est fausse,nextLine()
retourne une chaîne vide, renvoie un secondnextLine()
"too many!"
; scanner est maintenant à juste après la deuxième[enter]
. -
hasNextInt()
est vrai, revientnextInt()
0
; scanner est maintenant à juste avant la troisième[enter]
.
Voici un exemple de mettre certaines de ces choses ensemble. Vous pouvez expérimenter avec elle pour étudier comment fonctionne Scanner
.
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);
Disons que l'entrée est:
He is probably close to 100 now...[enter]
Elvis, of course[enter]
Ensuite, la dernière ligne de la sortie est:
[Elvis, of course] is 100 years old
Autres conseils
Je vraiment, n'aime vraiment pas en général utilisant le même appel de la bibliothèque pour la lecture et l'analyse syntaxique. bibliothèques de langues semblent être très rigides et souvent juste ne peut pas être plié à votre volonté.
La première étape qui extrait des données de System.in ne devrait pas être en mesure d'échouer, donc l'avoir lu comme une chaîne dans une variable, puis convertir cette variable de chaîne à un int. Si la conversion échoue, grande -. Imprimer votre erreur et continuer
Lorsque vous enroulez votre flux avec quelque chose qui peut lancer une exception, il devient assez confus juste quel état tout ce gâchis laisse votre flux dans.
Il est toujours un avantage pour Vous votre application lancer une erreur en cas d'erreur opposé à des façons de garder de se produire.
Une alternative consiste à placer le code dans un bloc de try {...}
catch {...}
pour InputMismatchException
.
Vous pouvez également placer le code dans une boucle de while
avoir le donjon de Scanner
incitant jusqu'à ce qu'une condition spécifique soit remplie.