Wie spüle ich den Cin-Puffer?


Antworten:


101

Möglicherweise:

std::cin.ignore(INT_MAX);

Dies würde alles einlesen und ignorieren, bis EOF. (Sie können auch ein zweites Argument angeben, das das zu lesende Zeichen ist (z. '\n'B. um eine einzelne Zeile zu ignorieren).

Außerdem: Sie möchten wahrscheinlich auch std::cin.clear();vorher ein: ausführen, um den Stream-Status zurückzusetzen.


10
(Alt, ich weiß.) Löschen Sie lieber vorher, damit der Stream in einen guten Zustand versetzt wird, in dem er mit seinem Puffer arbeiten kann.
GManNickG

Danke, GMan! Habe es zuerst falsch gemacht und einige Zeit damit verbracht, nach meinem Fehler zu suchen.
Balu

@GManNickG, habe gerade die Antwort korrigiert.
bwDraco

@DragonLord: Offensichtliche Lösung, die ich im Nachhinein hätte machen sollen, danke. :)
GManNickG

3
Ich wollte nur darauf hinweisen, dass ich für meinen Fall das '\ n' für notwendig halte. Andernfalls funktioniert das nachfolgende "cin >>" nicht.
Cardin

114

Ich würde die C ++ - Größenbeschränkungen den C-Versionen vorziehen:

// Ignore to the end of file
cin.ignore(std::numeric_limits<std::streamsize>::max())

// Ignore to the end of line
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')

15
Noch wichtiger ist, dass die Werte unterschiedlich sein können! (Streamsize muss nicht int sein)

2
Könnten Sie bitte ein Beispiel anführen, bei dem wir bis zum Ende der Datei ignorieren müssen, denn wenn ich cindie erste Anweisung oben verwende und verwende, um den cinPuffer zu leeren , werden Sie so lange zur Eingabe aufgefordert , bis ich sie EOFdurch Drücken ctrl+deingebe.
Ajay

@ajay: Nein. Das ist etwas, was du entscheiden musst. Ich erkläre lediglich, was das oben genannte tun wird.
Martin York

23
cin.clear();
fflush(stdin);

Dies war das einzige, was für mich beim Lesen von der Konsole aus funktioniert hat. In jedem anderen Fall würde es entweder unbegrenzt lesen, weil \ n fehlt, oder es würde etwas im Puffer verbleiben.

EDIT: Ich fand heraus, dass die vorherige Lösung die Dinge noch schlimmer machte. DIESES funktioniert jedoch:

cin.getline(temp, STRLEN);
if (cin.fail()) {
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
}

13

Ich habe zwei Lösungen dafür gefunden.

Das erste und einfachste ist zum std::getline()Beispiel:

std::getline(std::cin, yourString);

... das den Eingabestream verwirft, wenn er in eine neue Zeile gelangt. Lesen Sie mehr über diese Funktion hier .

Eine andere Option, die den Stream direkt verwirft, ist diese ...

#include <limits>
// Possibly some other code here
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');

Viel Glück!


9
int i;
  cout << "Please enter an integer value: ";

  // cin >> i; leaves '\n' among possible other junk in the buffer. 
  // '\n' also happens to be the default delim character for getline() below.
  cin >> i; 
  if (cin.fail()) 
  {
    cout << "\ncin failed - substituting: i=1;\n\n";
    i = 1;
  }
  cin.clear(); cin.ignore(INT_MAX,'\n'); 

  cout << "The value you entered is: " << i << " and its double is " << i*2 << ".\n\n";

  string myString;
  cout << "What's your full name? (spaces inclded) \n";
  getline (cin, myString);
  cout << "\nHello '" << myString << "'.\n\n\n";


4

Ich bevorzuge:

cin.clear();
fflush(stdin);

Es gibt ein Beispiel, in dem cin.ignore es einfach nicht schneidet, aber ich kann im Moment nicht daran denken. Es ist eine Weile her, als ich es benutzen musste (mit Mingw).

Fflush (stdin) ist jedoch gemäß dem Standard ein undefiniertes Verhalten. fflush () ist nur für Ausgabestreams gedacht. fflush (stdin) scheint nur unter Windows (zumindest mit GCC- und MS-Compilern) wie erwartet als Erweiterung des C-Standards zu funktionieren .

Wenn Sie es verwenden, ist Ihr Code also nicht portabel.

Siehe Verwenden von fflush (stdin) .

Eine Alternative finden Sie auch unter http://ubuntuforums.org/showpost.php?s=9129c7bd6e5c8fd67eb332126b59b54c&p=452568&postcount=1 .


9
fflush (stdin); ist undefiniertes Verhalten (in der Programmiersprache C), ausdrücklich in 7.18.5.2/2
Cubbi

1
+1 für die Lieferung eines gültigen, funktionierenden Kludges. Einige Menschen haben Jobs, andere haben Standards.
Mikhail

5
@Mikhail: Ihr Job sollte das Schreiben von standardkonformem Code beinhalten. Ich werde in Zukunft vermeiden, etwas zu verwenden, was Sie geschrieben haben.
Ed S.

4

Eine andere mögliche (manuelle) Lösung ist

cin.clear();
while (cin.get() != '\n') 
{
    continue;
}

Ich kann fflush oder cin.flush () nicht mit CLion verwenden, daher war dies praktisch.


Endlosschleife für mich.
StarWind0

Es funktioniert nur, wenn es ein Zeilenende gibt, sonst Endlosschleife
Bobul Mentol

2

Einfachster Weg:

cin.seekg(0,ios::end);
cin.clear();

Es positioniert nur den cin-Zeiger am Ende des stdin-Streams und cin.clear () löscht alle Fehlerflags wie das EOF-Flag.


1

Folgendes sollte funktionieren:

cin.flush();

Auf einigen Systemen ist es nicht verfügbar und dann können Sie Folgendes verwenden:

cin.ignore(INT_MAX);

1
Warum manuell eine Schleife schreiben, wenn Sie erkennen können, dass die gelesenen INT_MAX-Zeichen ignoriert werden, bis EOF (der Standardwert des zweiten Parameters) erreicht ist?
Evan Teran

Gunnar, vielleicht ist es besser, Ihren Beitrag zu bearbeiten, um dies widerzuspiegeln, nur für den Fall.
Dana the Sane

1
Soweit ich das beurteilen kann, dient die flushMethode nur zur Ausgabe und behandelt bereits geschriebene Zeichen.
Marc van Leeuwen

cin.flush ():basic_istream<char>' has no member named 'flush'
Eric

1
#include <stdio_ext.h>

und dann Funktion verwenden

__fpurge(stdin)

0

cin.get() scheint es seltsamerweise automatisch zu spülen (wahrscheinlich jedoch nicht bevorzugt, da dies verwirrend und wahrscheinlich temperamentvoll ist).


0

Es hat bei mir funktioniert. Ich habe for-Schleife mit getline () verwendet.

cin.ignore()
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.