Ich benutze die Scanner
Methoden nextInt()
und nextLine()
zum Lesen von Eingaben.
Es sieht aus wie das:
System.out.println("Enter numerical value");
int option;
option = input.nextInt(); // Read numerical value from input
System.out.println("Enter 1st string");
String string1 = input.nextLine(); // Read 1st string (this is skipped)
System.out.println("Enter 2nd string");
String string2 = input.nextLine(); // Read 2nd string (this appears right after reading numerical value)
Das Problem ist, dass nach Eingabe des numerischen Werts der erste input.nextLine()
übersprungen und der zweite input.nextLine()
ausgeführt wird, sodass meine Ausgabe folgendermaßen aussieht:
Enter numerical value
3 // This is my input
Enter 1st string // The program is supposed to stop here and wait for my input, but is skipped
Enter 2nd string // ...and this line is executed and waits for my input
Ich habe meine Anwendung getestet und es sieht so aus, als ob das Problem in der Verwendung liegt input.nextInt()
. Wenn ich es lösche, werden beide string1 = input.nextLine()
und string2 = input.nextLine()
so ausgeführt, wie ich es möchte.
java
io
java.util.scanner
blekione
quelle
quelle
Antworten:
Dies liegt daran, dass die
Scanner.nextInt
Methode das Zeilenumbruchzeichen in Ihrer Eingabe nicht liest, das durch Drücken der Eingabetaste erstellt wurde, und daher der Aufruf vonScanner.nextLine
nach dem Lesen dieser Zeilenumbruch zurückkehrt .Sie werden auf ein ähnliches Verhalten stoßen, wenn Sie
Scanner.nextLine
afterScanner.next()
oder eine andereScanner.nextFoo
Methode (außer sichnextLine
selbst) verwenden.Problemumgehung:
Setzen entweder einen
Scanner.nextLine
Anruf nach jedemScanner.nextInt
oderScanner.nextFoo
zu konsumieren Rest der Zeile einschließlich NewlineOder, noch besser, lesen Sie die Eingabe durch
Scanner.nextLine
und konvertieren Sie Ihre Eingabe in das richtige Format, das Sie benötigen. Beispielsweise können Sie mithilfe derInteger.parseInt(String)
Methode in eine Ganzzahl konvertieren .quelle
try-catch
, weilInteger.parseInt
wirft,NumberFormatException
wenn ein ungültiges Argument an es übergeben wird. Sie werden später etwas über Ausnahmen erfahren. Für EG: -Integer.parseInt("abc")
. Sie möchten nicht, dass "abc" in int konvertiert wird, oder?Scanner#hasNextFoo
vorherigen Scheck anstelle eines Try-Catch, aber das funktioniert auch.Das Problem ist mit dem Methode input.nextInt () , die nur den Wert int liest. Wenn Sie also mit input.nextLine () weiterlesen, erhalten Sie die Eingabetaste "\ n". Um dies zu überspringen, müssen Sie die input.nextLine () hinzufügen . Hoffe das sollte jetzt klar sein.
Versuchen Sie es so:
quelle
nextLine
Wenn Sie eine Nummer eingeben und dann drücken Enter, wird
input.nextInt()
nur die Nummer verbraucht, nicht das "Zeilenende". Bei derinput.nextLine()
Ausführung wird das noch im Puffer befindliche "Zeilenende" von der ersten Eingabe verbraucht.Verwenden Sie stattdessen
input.nextLine()
sofort danachinput.nextInt()
quelle
Es scheint viele Fragen zu diesem Thema zu geben
java.util.Scanner
. Ich denke, eine besser lesbare / idiomatische Lösung wäre, aufzurufenscanner.skip("[\r\n]+")
, um nach dem Aufruf alle Zeilenumbrüche zu löschennextInt()
.BEARBEITEN: Wie unten bei @PatrickParker angegeben, führt dies zu einer Endlosschleife, wenn der Benutzer nach der Nummer ein Leerzeichen eingibt. In der Antwort finden Sie ein besseres Muster für das Überspringen: https://stackoverflow.com/a/42471816/143585
quelle
input.nextInt();
Dies geschieht, weil der Zeilenumbruch nicht erfasst wird. Sie könnten wie die anderen vorgeschlagenen tun, indem Sie eineinput.nextLine();
darunter hinzufügen .Alternativ können Sie es im C # -Stil tun und eine nextLine in eine Ganzzahl wie folgt analysieren:
Dies funktioniert genauso gut und spart Ihnen eine Codezeile.
quelle
TL; DR Verwendung
scanner.skip("\\R")
vor jedemscanner.newLine()
Aufruf, der ausgeführt wird nach:scanner.next()
scanner.next*TYPE*()
Methode.Dinge, die Sie wissen müssen:
Text, der nur wenige Zeilen darstellt, enthält auch nicht druckbare Zeichen zwischen Zeilen (wir nennen sie Zeilentrennzeichen) wie
"\r"
)"\n"
)Wenn Sie Daten von der Konsole lesen, kann der Benutzer seine Antwort eingeben, und wenn er fertig ist, muss er dies irgendwie tun diese Tatsache bestätigen. Dazu muss der Benutzer die Eingabetaste / Eingabetaste auf der Tastatur drücken.
Wichtig ist, dass dieser Schlüssel neben der Sicherstellung, dass Benutzerdaten in die Standardeingabe (dargestellt durch
System.in
die gelesen wirdScanner
) gestellt werden, auch betriebssystemabhängige Zeilentrennzeichen (wie bei Windows\r\n
) nachträglich sendet .Wenn Sie also den Benutzer nach einem Wert wie fragen
age
und Benutzertypen 42 eingeben und die Eingabetaste drücken, enthält die Standardeingabe"42\r\n"
.Problem
Scanner#nextInt
(und andere Methoden) erlaubt es nicht , Scanner zu verbrauchen diese Zeilenseparatoren. Es wird sich von lesen (wie sonst Scanner würde wissen , dass es nicht mehr Ziffern von dem Benutzer , die repräsentieren Wert als Leerzeichen gegenüber ?) , Die sie von der Standardeingabe entfernen, aber es wird auch cachen diese Zeilenseparatoren intern . Wir müssen uns daran erinnern, dass alle Scannermethoden immer ausgehend vom zwischengespeicherten Text scannen.Scanner#nextType
System.in
age
Jetzt werden
Scanner#nextLine()
einfach alle Zeichen gesammelt und zurückgegeben, bis Zeilentrennzeichen (oder das Ende des Streams) gefunden werden. Da Zeilentrennzeichen nach dem Lesen der Nummer von der Konsole sofort im Cache des Scanners gefunden werden, wird eine leere Zeichenfolge zurückgegeben, was bedeutet, dass Scanner vor diesen Zeilentrennzeichen (oder dem Ende des Streams) kein Zeichen finden konnte.BTW
nextLine
auch verbraucht diese Zeilenseparatoren.Lösung
Also , wenn Sie wollen Nummer fragen und dann für ganze Zeile während der leeren Zeichenfolge als Ergebnis zu vermeiden
nextLine
, entwedernextInt
von Scanner-Cache vonnextLine
,skip("\\R")
oderskip("\r\n|\r|\n")
den Scanner überspringen lassen, der mit einem Zeilentrennzeichen übereinstimmt (weitere Informationen zu\R
: https://stackoverflow.com/a/31060125 )nextInt
(next
odernextTYPE
Methoden). Lesen Sie stattdessen die gesamten Daten Zeile für Zeile mitnextLine
und analysieren Sie die Nummern aus jeder Zeile (vorausgesetzt, eine Zeile enthält nur eine Nummer), um den richtigen Typ wieint
via zu erhaltenInteger.parseInt
.Übrigens : Methoden können Trennzeichen (standardmäßig alle Leerzeichen wie Tabulatoren, Zeilentrennzeichen) einschließlich der vom Scanner zwischengespeicherten Trennzeichen überspringen , bis sie den nächsten Nicht-Trennzeichenwert (Token) finden. Vielen Dank für die Eingabe wie Code
Scanner#nextType
"42\r\n\r\n321\r\n\r\n\r\nfoobar"
wird in der Lage sein, richtig zuzuweisen
num1=42
num2=321
name=foobar
.quelle
Anstelle der
input.nextLine()
Verwendunginput.next()
sollte dies das Problem lösen.Geänderter Code:
quelle
Wenn Sie sowohl Zeichenfolgen als auch Ints lesen möchten, können Sie zwei Scanner verwenden:
quelle
scanner.nextLine()
sollte funktionieren.Wenn Sie Eingaben schnell scannen möchten, ohne in die nextLine () -Methode der Scannerklasse verwirrt zu werden, verwenden Sie dafür den benutzerdefinierten Eingabescanner.
Code:
Vorteile:
Methoden:
Verwendungszweck :
ScanReader sc = new ScanReader(System.in);
3. Importieren Sie die erforderlichen Klassen:import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream;
4. Lösen Sie IOException von Ihrer Hauptmethode aus, um Exception zu behandeln. 5. Verwenden Sie Provided Methods. 6. Genießen SieBeispiel:
quelle
Um das Problem zu vermeiden, verwenden Sie es
nextLine();
sofort danach,nextInt();
da es beim Löschen des Puffers hilft. Wenn Sie drückenENTER
dienextInt();
nicht die neue Linie erfassen und daher überspringt dieScanner
später Code.quelle
sc.nextLine()
ist besser als das Parsen der Eingabe. Weil es in Bezug auf die Leistung gut sein wird.quelle
Ich denke ich bin ziemlich spät zur Party ..
Wie bereits erwähnt,
input.nextLine()
löst ein Aufruf nach dem Abrufen Ihres int-Werts Ihr Problem. Der Grund, warum Ihr Code nicht funktionierte, war, dass Sie nichts anderes von Ihrer Eingabe (in die Sie das int eingegeben haben) speichern konntenstring1
. Ich werde nur ein wenig mehr Licht auf das gesamte Thema werfen.Betrachten Sie nextLine () als die ungerade unter den nextFoo () -Methoden in der Scanner-Klasse. Nehmen wir ein kurzes Beispiel. Nehmen wir an, wir haben zwei Codezeilen wie die folgenden:
Wenn wir den folgenden Wert eingeben (als einzelne Eingabezeile)
Der Wert von our
firstNumber
undsecondNumber
variable wird zu 54 bzw. 234. Der Grund, warum dies so funktioniert, ist, dass ein neuer Zeilenvorschub ( dh \ n ) NICHT automatisch generiert wird, wenn die nextInt () -Methode die Werte aufnimmt. Es dauert einfach das "nächste int" und geht weiter. Dies gilt auch für die übrigen nextFoo () -Methoden mit Ausnahme von nextLine ().nextLine () generiert unmittelbar nach der Eingabe eines Werts einen neuen Zeilenvorschub. Dies ist, was @RohitJain bedeutet, wenn gesagt wird, dass der neue Zeilenvorschub "verbraucht" ist.
Schließlich nimmt die next () -Methode einfach den nächsten String ohne eine neue Zeile generieren. Dies macht dies zur bevorzugten Methode, um separate Strings innerhalb derselben einzelnen Zeile zu erstellen.
Ich hoffe das hilft .. Frohe Codierung!
quelle
Verwenden Sie 2 Scannerobjekte anstelle von einem
quelle
quelle
wenn ich eine nicht leere Eingabe erwarte
im obigen Beispiel verwendet:
quelle
In einem meiner Anwendungsfälle hatte ich das Szenario, einen Zeichenfolgenwert zu lesen , dem einige ganzzahlige Werte vorangestellt waren . Ich musste eine " for / while-Schleife " verwenden, um die Werte zu lesen. Und keiner der oben genannten Vorschläge hat in diesem Fall funktioniert.
Verwenden
input.next()
stattinput.nextLine()
beheben das Problem. Ich hoffe, dies könnte für diejenigen hilfreich sein, die sich mit einem ähnlichen Szenario befassen.quelle
Verwenden Sie diesen Code, um Ihr Problem zu beheben.
quelle
Da
nextXXX()
Methoden nicht lesennewline
, außernextLine()
. Wir können dasnewline
nach dem Lesen eines beliebigennon-string
Wertes (int
in diesem Fall) überspringen, indem wirscanner.skip()
Folgendes verwenden:quelle
Warum nicht für jede Lesung einen neuen Scanner verwenden? Wie unten. Mit diesem Ansatz werden Sie Ihr Problem nicht konfrontieren.
quelle
Scanner
, um Speicherverlust zu verhindern. Zeit verschwenden?nextInt()
verbraucht die Newline nicht, unabhängig davon, ob es sich um eine "neue"Scanner
oder eine bereits verwendete handelt.