c++ getline() wartet nicht auf Eingaben von der Konsole, wenn es mehrmals aufgerufen wird

Lesezeit: 4 Minuten

c getline wartet nicht auf Eingaben von der Konsole wenn
Benutzer754852

Ich versuche, ein paar Benutzereingabeparameter von der Konsole zu bekommen, zwei Strings, zwei Ints und ein Double. Der relevante Code, den ich zu verwenden versuche, ist dieser:

#include <string>
#include <iostream>
using namespace std;

// ...

string inputString;
unsigned int inputUInt;
double inputDouble;

// ...

cout << "Title: "; 
getline(cin, inputString);
tempDVD.setTitle(inputString);

cout << "Category: "; 
getline(cin, inputString);
tempDVD.setCategory(inputString);

cout << "Duration (minutes): "; 
cin >> inputUInt; 
tempDVD.setDuration(inputUInt);

cout << "Year: "; 
cin >> inputUInt; 
tempDVD.setYear(inputUInt);

cout << "Price: $"; 
cin >> inputDouble; 
tempDVD.setPrice(inputDouble);

Beim Ausführen des Programms wird der Code jedoch nicht bis zum zweiten Aufruf von getline() angehalten, anstatt auf die Eingabe des ersten inputString zu warten. Die Konsolenausgabe sieht also so aus:

Titel: Kategorie:

wobei der Cursor hinter der Kategorie erscheint. Wenn ich jetzt eintippe, springt das Programm zur Jahreseingabe und erlaubt mir nicht, mehr als eine Zeichenfolge einzugeben. Was passiert hier?

  • Kann nicht reproduzieren; Bitte poste echten, vollständigen Code. Ich wette, dein Problem liegt woanders. Mischen Sie auch keine formatierten Eingaben und getline().

    – Kerrek SB

    16. Oktober 2011 um 20:18 Uhr

  • @KerrekSB: Ich stimme zu, dass das Mischen ein Symptom für schlechten Stil ist, aber was ist der objektive Grund dafür, sie nicht zu mischen? Ich denke, es ist vollkommen richtig, sie zu mischen, wirklich.

    – sehen

    16. Oktober 2011 um 20:21 Uhr

  • @sehe: Das Problem ist, dass die formatierte Extraktion die Zeilenumbrüche nicht verbraucht, daher ist es sehr einfach, unerwartete Ergebnisse zu erhalten, wenn Sie dies tun getline() nachdem Sie dachten, dass Sie bereits die gesamte vorangegangene Zeile verarbeitet haben. Ich sage nicht, dass es unmöglich ist, aber es macht die Logik oft sehr schwer zu lesen und aufrechtzuerhalten.

    – Kerrek SB

    16. Oktober 2011 um 20:22 Uhr

  • Entschuldigung für den unvollständigen Code; Das Programm war lang. Ich denke jetzt, dass das Problem mit einer früheren Verwendung eines Cins zusammenhängt, um ein Int vor diesem Block zu erhalten.

    – Benutzer754852

    16. Oktober 2011 um 20:30 Uhr

Das Problem ist, dass Sie Aufrufe von getline() mit der Verwendung des Operators >> mischen.

Denken Sie daran, dass der Operator >> führende Leerzeichen ignoriert hat, sodass er korrekt über die Zeilengrenzen hinweg fortgesetzt wird. Hört jedoch auf zu lesen, nachdem die Eingabe erfolgreich abgerufen wurde, und verschluckt daher keine nachgestellten ‘\n’-Zeichen. Wenn Sie also ein getline() nach einem >> verwenden, erhalten Sie normalerweise das Falsche, es sei denn, Sie sind vorsichtig (um zuerst das nicht gelesene Zeichen ‘\n’ zu entfernen).

Der Trick besteht darin, nicht beide Arten von Eingaben zu verwenden. Wählen Sie das Passende aus und bleiben Sie dabei.

Wenn es sich nur um Zahlen handelt (oder um Objekte, die gut mit dem Operator >> spielen), verwenden Sie einfach den Operator >> (Notenzeichenfolge ist der einzige grundlegende Typ, der nicht symmetrisch zur Eingabe / Ausgabe ist (dh nicht gut spielt)).

Wenn die Eingabe Zeichenfolgen oder eine Kombination von Dingen enthält, für die getline() erforderlich ist, verwenden Sie nur getline() und analysieren Sie die Zahl aus der Zeichenfolge.

std::getline(std::cin, line);
std::stringstream  linestream(line);

int  value;
linestream >> value;

// Or if you have boost:
std::getline(std::cin, line);
int  value = boost::lexical_cast<int>(line);

Sie müssen den Eingabepuffer leeren. Es kann damit gemacht werden cin.clear(); cin.sync();.

  • Seltsamerweise funktioniert es bei mir nicht mit der Kombination von denen. Es funktioniert nur mit std::cin.ignore().

    – KeyC0de

    7. August 2018 um 1:18 Uhr

Sie können verwenden

cin.ignore();

oder wie von @kernald erwähnt verwenden

cin.clear();
cin.sync();

vor der Verwendung von getline()

c getline wartet nicht auf Eingaben von der Konsole wenn
Farbod Ahmadian

Wenn der Benutzer ein Leerzeichen vor \n im vorherigen eingibt cin Vor getlinenur ignorieren selbst würde nicht ausreichen, also müssen Sie stattdessen diesen Code verwenden ignorieren() allein. Zum Beispiel 12345 \t \n wird nicht mehr funktionieren. Alle unverarbeiteten Zeichen müssen ignoriert werden.

#include <limits>
cin.ignore(numeric_limits<streamsize>::max(), '\n');

Verwenden Sie diese zwischen cin und getline.

  • Danke. Der Code funktioniert nur, wenn sowohl cin.clear() als auch cin.sync() verwendet werden.

    – Benutzer754852

    16. Oktober 2011 um 20:26 Uhr

  • Der einfachste Weg, den >>-Operator mit der getline()-Methode zu kombinieren, besteht darin, cin.ignore() vor jedem Aufruf von getline einzugeben, damit der Eingabepuffer von allen übrig gebliebenen Zeilenumbruchzeichen aus der vorherigen Eingabe gelöscht wird.

    – Corey Zambonie

    24. Juni 2015 um 16:46 Uhr

Funktioniert auch mit ws. Sie können verwenden getline(cin >> ws, inputString)), um die Leerzeichen oder die Zeilenumbrüche nach dem Lesen von Daten zu essen cin Befehl.

1646265613 846 c getline wartet nicht auf Eingaben von der Konsole wenn
Unix-Ninja

Das Mischen von getline() mit Eingabeströmen ist im Allgemeinen eine schlechte Sache. Es ist theoretisch möglich, die schmutzigen Puffer, die durch die Verwendung von Streams übrig bleiben, manuell zu handhaben, aber es ist ein unnötiger Schmerz, der auf jeden Fall vermieden werden sollte.

Sie sind besser dran, eine Konsolenbibliothek zu verwenden, um Ihre Eingaben zu erfassen, auf diese Weise kann die Drecksarbeit für Sie abstrahiert werden.

Schau dir TinyCon an. Sie können einfach die statische Methode tinyConsole::getLine() anstelle Ihrer getline- und stream-Aufrufe verwenden, und Sie können sie so oft verwenden, wie Sie möchten.

Informationen finden Sie hier:
https://sourceforge.net/projects/tinycon/

1646265614 578 c getline wartet nicht auf Eingaben von der Konsole wenn
Gurudev

cin.sync(); Verwenden Sie dies anstelle von cin.ignore( funktioniert am besten.

917500cookie-checkc++ getline() wartet nicht auf Eingaben von der Konsole, wenn es mehrmals aufgerufen wird

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy