Problem mit cin zweimal

8

Hier ist der Code:

%Vor%

Das Ergebnis ist, dass getline niemals für Benutzereingaben pausiert, daher ist die zweite Ausgabe immer leer.

Nachdem ich etwas Zeit damit verbracht habe, merke ich nach dem ersten Aufruf "cin & gt; & gt; str", dass '\ n' immer noch in cin gespeichert ist (mit cin.peek ()), was die getline sofort beendet . Die Lösung fügt eine weitere Zeile zwischen der ersten und der zweiten hinzu: cin.ignore(numeric_limits::max(), '\n');

Allerdings verstehe ich immer noch nicht, warum ist '\ n' dort nach dem ersten Anruf geblieben? Was macht istream & amp; Betreiber & gt; & gt; wirklich tun?

    
gc . 26.03.2010, 17:30
quelle

6 Antworten

0

Gute Beschreibung, die einige der Gründe erklärt, warum Sie auf dieses Problem stoßen, hauptsächlich wegen der Verhalten der Eingabetypen und dass Sie sie mischen

    
curtisk 26.03.2010, 17:38
quelle
7

Das \n wird im Eingabestream gemäß der Art und Weise gelassen, in der operator>> für std::string definiert ist. Der std::string wird mit Zeichen aus dem Eingabestream gefüllt, bis ein Leerzeichen gefunden wird (in diesem Fall \n ). An diesem Punkt stoppt die Füllung und das Leerzeichen ist jetzt das nächste Zeichen im Eingabestream.

Sie können \n auch entfernen, indem Sie direkt nach cin.get() cin>>str aufrufen. Es gibt viele, viele verschiedene Möglichkeiten, diese spezielle I / O-Katze zu enthäuten. (Vielleicht eine gute Frage an und für sich?)

    
fbrereto 26.03.2010 17:34
quelle
2

Ich empfehle generell nur eine linienorientierte Eingabe von std :: cin. Ihr Code könnte also etwa so aussehen:

%Vor%

Achten Sie darauf, auch die Fehlerprüfung hinzuzufügen.

Der Nur-Zeilen-Ansatz vermeidet es, über die Zeilenpufferung der Eingabe nachzudenken, die Eingabe zu löschen usw. Wenn Sie etwas direkt mit & gt; & gt; lesen, wird die Eingabe nicht beendet, wenn der Benutzer die Eingabe eingibt was erforderlich ist, aber stattdessen fortgesetzt wird, bis ein Token eingegeben wird (dieses Verhalten ist normalerweise nicht erwünscht).

    
Tronic 26.03.2010 17:58
quelle
2

Wie andere bereits gesagt haben, besteht das Problem darin, dass der Zeilenumbruch von der ersten Extraktion übrig bleibt. Eine Lösung, die ich mache, ist, alle linken Zeichen im Stream zu verwerfen:

%Vor%     
AraK 26.03.2010 17:41
quelle
1

Standardmäßig liest der Stream-Insertion-Operator, bis er Leerzeichen sieht. Ihr erster Anruf wird erst zurückgegeben, wenn ein Leerzeichen, ein Tabulator, ein Zeilenumbruch usw. angezeigt wird. Dann muss das nächste Zeichen verbraucht werden, damit Sie zum nächsten Zeichen gelangen können.

    
jwismar 26.03.2010 17:34
quelle
0

suchte auch nach der am besten geeigneten Lösung. Die Implementierung dieses Operators könnte zu Problemen führen. Und es ist nicht immer akzeptabel, ganze Zeilen zu lesen oder verschiedene Typen in einer Eingabezeile zu mischen.

Um das Problem zu lösen, wenn Sie einige Daten aus cin lesen möchten und nicht wissen, ob die Whitespaces nach der letzten Eingabeoperation korrekt extrahiert wurden, können Sie Folgendes tun:

%Vor%

Sie können dies jedoch nicht verwenden, um das nachfolgende Zeilensymbol nach der letzten Eingabeoperation von cin zu löschen, um die neue Eingabe nicht zu beeinflussen, da std::ws alle Leerzeichen verbraucht und die Kontrolle erst beim ersten Nicht-ws-Zeichen oder% co_de zurückgibt % wird gefunden, so dass das Drücken der Eingabetaste den Eingabevorgang nicht beendet. In diesem Fall sollte

verwendet werden %Vor%

was flexibler ist.

P.S. Wenn Fehler mit EOF -Funktion wie "Bezeichner erwartet" erhalten wurde, könnte dies durch max() -Makros verursacht werden, die in einem Header definiert wurden (z. B. von Microsoft); Dies könnte mit

behoben werden %Vor%     
B-GangsteR 08.08.2016 23:22
quelle

Tags und Links