Wie verhindere ich, dass ein Scanner Ausnahmen auslöst, wenn der falsche Typ eingegeben wird?
-
21-09-2019 - |
Frage
Hier ist ein Beispielcode:
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) ;
}
}
Wenn ich das Programm starte und ihm eine gebe int
wie 4
, dann geht alles gut.
Andererseits, wenn ich antworte too many
Es lacht nicht über meinen lustigen Witz.Stattdessen bekomme ich Folgendes (wie erwartet):
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)
Gibt es eine Möglichkeit, es zu ignorieren, um Einträge zu ignorieren, die keine INTs sind, oder mit "Wie viele eindringen?" Ich würde gerne wissen, wie man beide macht.
Lösung
Sie können einen der vielen verwenden hasNext*
Methoden, die Scanner
hat für die Vorvalidierung.
if (in.hasNextInt()) {
int a = in.nextInt() ;
System.out.println(a);
} else {
System.out.println("Sorry, couldn't understand you!");
}
Dies verhindert InputMismatchException
von sogar geworfen werden, weil Sie immer sicherstellen, dass es es WILLE Passen Sie passen, bevor Sie es lesen.
java.util.Scanner API
boolean hasNextInt()
: Kehrt zurücktrue
Wenn das nächste Token in der Eingabe dieses Scanners als INT -Wert im Standardradix interpretiert werden kannnextInt()
Methode. Der Scanner findet keine Eingabe vorbei.String nextLine()
: Fördert diesen Scanner über die aktuelle Linie hinaus und gibt den Eingang zurück, der übersprungen wurde.
Beachten Sie die Abschnitte fett. hasNextInt()
Fortschritt nicht über irgendwelche Eingaben. Wenn es zurückkehrt true
, Sie können den Scanner durchrufen nextInt()
, was nicht werfen wird InputMismatchException
.
Wenn es zurückkehrt false
, Dann müssen Sie den "Müll" vorbeispringen. Der einfachste Weg, dies zu tun, ist nur durch Anrufe nextLine()
, wahrscheinlich zweimal aber mindestens einmal.
Warum müssen Sie möglicherweise tun nextLine()
Zweimal ist Folgendes: Angenommen, dies ist die eingegebene Eingabe:
42[enter]
too many![enter]
0[enter]
Nehmen wir an, der Scanner befindet sich am Anfang dieser Eingabe.
hasNextInt()
ist wahr,nextInt()
kehrt zurück42
; Scanner ist jetzt bei kurz bevor Der Erste[enter]
.hasNextInt()
ist falsch,nextLine()
Gibt eine leere Zeichenfolge zurück, eine SekundenextLine()
kehrt zurück"too many!"
; Scanner ist jetzt bei kurz nachdem der Zweite[enter]
.hasNextInt()
ist wahr,nextInt()
kehrt zurück0
; Scanner ist jetzt bei kurz bevor der dritte[enter]
.
Hier ist ein Beispiel dafür, einige dieser Dinge zusammenzusetzen. Sie können damit experimentieren, um zu untersuchen, wie Scanner
Arbeiten.
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);
Nehmen wir an, die Eingabe lautet:
He is probably close to 100 now...[enter]
Elvis, of course[enter]
Dann ist die letzte Zeile der Ausgabe:
[Elvis, of course] is 100 years old
Andere Tipps
Im Allgemeinen mag ich es überhaupt nicht, denselben Bibliotheksaufruf sowohl zum Lesen als auch zum Parsen zu verwenden.Sprachbibliotheken scheinen sehr unflexibel zu sein und lassen sich oft einfach nicht Ihrem Willen anpassen.
Der erste Schritt, bei dem Daten aus System.in abgerufen werden, sollte nicht fehlschlagen. Lassen Sie sie also als Zeichenfolge in eine Variable einlesen und konvertieren Sie diese Zeichenfolgenvariable dann in eine Ganzzahl.Wenn die Konvertierung fehlschlägt, drucken Sie den Fehler aus und fahren Sie fort.
Wenn Sie Ihren Stream mit etwas umschließen, das eine Ausnahme auslösen kann, wird es etwas verwirrend, in welchem Zustand das ganze Durcheinander Ihren Stream zurücklässt.
Es ist immer ein Vorteil für haben Ihre Anwendung macht einen Fehler, wenn ein Fehler auftritt behalten es passiert.
Eine Alternative besteht darin, den Code in a zu wickeln try {...}
catch {...}
Block für InputMismatchException
. Möglicherweise möchten Sie den Code auch in a einpacken while
Schleife, um die zu haben Scanner
Auffordern Sie weiter, bis ein bestimmter Zustand erfüllt ist.