¿Cómo limpio el búfer de cin?

Respuestas:

101

Posiblemente:

std::cin.ignore(INT_MAX);

Esto leería e ignoraría todo hasta EOF. (también puede proporcionar un segundo argumento que es el carácter a leer hasta (por ejemplo, '\n'para ignorar una sola línea).

Además: probablemente desee hacer un: std::cin.clear();antes de esto también para restablecer el estado de la transmisión.

Evan Terán
fuente
10
(Viejo, lo sé). Limpiar antes, más bien, para que la secuencia se ponga en un buen estado en el que pueda operar en su búfer.
GManNickG
¡Gracias, GMan! Lo hice de la manera incorrecta, primero, y pasé bastante tiempo buscando mi error.
Balu
@GManNickG, acaba de arreglar la respuesta.
bwDraco
@DragonLord: Solución obvia que debería haber hecho en retrospectiva, gracias. :)
GManNickG
3
Solo quería señalar que, para mi caso, encuentro el '\ n' necesario. De lo contrario, el "cin >>" subsiguiente no funciona.
Cardin
114

Preferiría las restricciones de tamaño de C ++ sobre las versiones de 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')
Martin York
fuente
15
Más importante aún, ¡los valores pueden ser diferentes! (streamsize no tiene que ser int)
2
¿Podría citar un ejemplo en el que debemos ignorar hasta el final del archivo porque si uso ciny uso la primera declaración anterior para vaciar el cinbúfer, sigue solicitando la entrada hasta que ingrese EOFpresionando ctrl+d?
ajay
@ajay: No. Eso es algo que tendrás que decidir. Simplemente estoy explicando lo que hará lo anterior.
Martin York
23
cin.clear();
fflush(stdin);

Esto fue lo único que funcionó para mí al leer desde la consola. En cualquier otro caso, se leería indefinidamente debido a la falta de \ n, o quedaría algo en el búfer.

EDITAR: Descubrí que la solución anterior empeoró las cosas. ESTE sin embargo, funciona:

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

He encontrado dos soluciones para esto.

La primera, y la más sencilla, es utilizar, std::getline()por ejemplo:

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

... que descartará el flujo de entrada cuando llegue a una nueva línea. Lea más sobre esta función aquí .

Otra opción que descarta directamente el stream es esta ...

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

¡Buena suerte!

Ben
fuente
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";
Martin York
fuente
4

Yo prefiero:

cin.clear();
fflush(stdin);

Hay un ejemplo en el que cin.ignore simplemente no funciona, pero no puedo pensar en ello en este momento. Fue hace un tiempo cuando necesitaba usarlo (con Mingw).

Sin embargo, fflush (stdin) es un comportamiento indefinido según el estándar. fflush () solo está diseñado para flujos de salida. fflush (stdin) solo parece funcionar como se esperaba en Windows (con compiladores GCC y MS al menos) como una extensión del estándar C .

Entonces, si lo usa, su código no será portátil.

Consulte Uso de fflush (stdin) .

Además, consulte http://ubuntuforums.org/showpost.php?s=9129c7bd6e5c8fd67eb332126b59b54c&p=452568&postcount=1 para obtener una alternativa.

Sombra2531
fuente
9
fflush (stdin); es Comportamiento indefinido (en el lenguaje de programación C), explícitamente indicado en 7.18.5.2/2
Cubbi
1
+1 por suministrar un kludge válido y de trabajo. Algunas personas tienen trabajos, otras tienen estándares.
Mikhail
5
@Mikhail: su trabajo debe incluir escribir código estándar compatible. Me aseguraré de evitar usar cualquier cosa que haya escrito en el futuro.
Ed S.
4

Otra posible solución (manual) es

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

No puedo usar fflush o cin.flush () con CLion, por lo que esto fue útil.

Bobul mentol
fuente
bucle infinito para mí.
StarWind0
Está funcionando solo si hay final de línea, de lo contrario bucle infinito
Bobul Mentol
2

La manera más fácil:

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

Simplemente coloca el puntero cin al final del flujo stdin y cin.clear () borra todos los indicadores de error, como el indicador EOF.

Chaitanya Vaishampayan
fuente
1

Lo siguiente debería funcionar:

cin.flush();

En algunos sistemas no está disponible y luego puede usar:

cin.ignore(INT_MAX);
Gunnar Steinn
fuente
1
por qué escribir manualmente un bucle cuando puede decir que ignore los caracteres INT_MAX leídos hasta que llegue a EOF (el valor predeterminado del segundo parámetro).
Evan Teran
Gunnar, podría ser mejor editar tu publicación para reflejar esto, por si acaso.
Dana the Sane
1
Por lo que puedo decir, el flushmétodo es solo para salida y trata con caracteres ya escritos.
Marc van Leeuwen
cin.flush ():basic_istream<char>' has no member named 'flush'
eric
1
#include <stdio_ext.h>

y luego usa la función

__fpurge(stdin)
techcomp
fuente
0

cin.get() parece vaciarlo automáticamente de manera bastante extraña (probablemente no sea el preferido, ya que esto es confuso y probablemente temperamental).

GuestPerson001
fuente
0

Funcionó para mí. He usado for loop con getline ().

cin.ignore()
Amrit Malla
fuente