Come faccio a svuotare il buffer cin?


Risposte:


101

Possibilmente:

std::cin.ignore(INT_MAX);

Questo avrebbe letto e ignorato tutto fino a quando EOF. (puoi anche fornire un secondo argomento che è il carattere da leggere fino a quando (es: '\n'per ignorare una singola riga).

Inoltre: probabilmente vorrai fare anche: std::cin.clear();prima di questo per ripristinare lo stato del flusso.


10
(Vecchio lo so.) Piuttosto chiaro prima, quindi il flusso viene messo in uno stato buono in cui può operare sul suo buffer.
GManNickG

Grazie, GMan! Prima ha sbagliato, e ho passato un bel po 'di tempo a cercare il mio errore.
balu

@GManNickG, ho appena corretto la risposta.
bwDraco

@ DragonLord: soluzione ovvia che avrei dovuto fare col senno di poi, grazie. :)
GManNickG

3
Volevo solo far notare che per il mio caso, trovo il "\ n" necessario. Altrimenti il ​​successivo "cin >>" non funziona.
Cardin

114

Preferirei i vincoli di dimensione C ++ rispetto alle versioni C:

// 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
Ancora più importante, i valori potrebbero essere diversi! (la dimensione dello streaming non deve essere int)

2
potresti citare un esempio in cui dobbiamo ignorare fino alla fine del file perché se uso cine utilizzo la prima istruzione sopra per svuotare il cinbuffer, continua a chiedere input fino a quando non accetto EOFpremendo ctrl+d?
giovedì

@ajay: No. Questo è qualcosa che dovrai decidere. Sto semplicemente spiegando cosa farà quanto sopra.
Martin York,

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

Questa è stata l'unica cosa che ha funzionato per me durante la lettura da console. In ogni altro caso potrebbe leggere indefinitamente a causa della mancanza di \ n, o qualcosa rimarrebbe nel buffer.

EDIT: ho scoperto che la soluzione precedente ha peggiorato le cose. QUESTO invece, funziona:

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

13

Ho trovato due soluzioni a questo.

Il primo, e più semplice, è usare std::getline()ad esempio:

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

... che scarterà il flusso di input quando arriverà a una nuova riga. Maggiori informazioni su questa funzione qui .

Un'altra opzione che scarta direttamente il flusso è questa ...

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

In bocca al lupo!


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

Preferisco:

cin.clear();
fflush(stdin);

C'è un esempio in cui cin.ignore non lo taglia, ma al momento non ci penso. Qualche tempo fa avevo bisogno di usarlo (con Mingw).

Tuttavia, fflush (stdin) è un comportamento non definito secondo lo standard. fflush () è pensato solo per flussi di output. fflush (stdin) sembra funzionare solo come previsto su Windows (con GCC e MS compilatori almeno) come un'estensione allo standard C .

Quindi, se lo usi, il tuo codice non sarà portabile.

Vedere Utilizzo di fflush (stdin) .

Inoltre, vedere http://ubuntuforums.org/showpost.php?s=9129c7bd6e5c8fd67eb332126b59b54c&p=452568&postcount=1 per un'alternativa.


9
fflush (stdin); è un comportamento indefinito (nel linguaggio di programmazione C), esplicitamente dichiarato così in 7.18.5.2/2
Cubbi

1
+1 per aver fornito un kludge valido e funzionante. Alcune persone hanno un lavoro, altre hanno degli standard.
Mikhail

5
@ Mikhail: il tuo lavoro dovrebbe includere la scrittura di codice conforme agli standard. Farò in modo di evitare di utilizzare qualsiasi cosa tu abbia scritto in futuro.
Ed S.

4

Un'altra possibile soluzione (manuale) è

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

Non posso usare fflush o cin.flush () con CLion, quindi questo è stato utile.


loop infinito per me.
StarWind0

Funziona solo se c'è la fine della riga, altrimenti loop infinito
Bobul Mentol

2

Modo più semplice:

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

Posiziona semplicemente il puntatore cin alla fine del flusso stdin e cin.clear () cancella tutti i flag di errore come il flag EOF.


1

Quanto segue dovrebbe funzionare:

cin.flush();

Su alcuni sistemi non è disponibile e quindi puoi utilizzare:

cin.ignore(INT_MAX);

1
perché scrivere manualmente un ciclo quando puoi dire di ignorare i caratteri INT_MAX letti fino a quando non raggiunge EOF (il valore predefinito del secondo parametro).
Evan Teran,

Gunnar, potrebbe essere meglio modificare il tuo post per riflettere questo, per ogni evenienza.
Dana the Sane

1
Per quanto ne so, il flushmetodo è solo per l'output e si occupa di caratteri già scritti.
Marc van Leeuwen

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

1
#include <stdio_ext.h>

e quindi utilizzare la funzione

__fpurge(stdin)

0

cin.get() sembra scaricarlo automaticamente in modo abbastanza strano (probabilmente non preferito, dato che questo è confuso e probabilmente di temperamento).


0

Ha funzionato per me. Ho usato il ciclo for con getline ().

cin.ignore()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.