Borrar búfer de entrada en C++

Jinku Hu 12 octubre 2023
Borrar búfer de entrada en C++

Este artículo demostrará varios métodos de cómo borrar el búfer de entrada en C++.

Utilice la función std::cin::ignore para borrar el búfer de entrada en C++

ignore es una función incorporada del objeto std::cin, y se puede usar para extraer y descartar caracteres del flujo de entrada hasta el delimitador dado. Antes de discutir el comportamiento de la función cin::ignore, debe tenerse en cuenta que los flujos de entrada y salida estándar como cin / cout están almacenados en búfer, lo que significa que existe cierta contabilidad entre las escrituras / lecturas del usuario y el estado real del búfer en el núcleo del sistema operativo. Este búfer es administrado por la propia biblioteca C++ y su propósito es hacer que las solicitudes de lectura / escritura sean más eficientes. Tenga en cuenta que llamar a los servicios del sistema operativo para cada byte sería un uso bastante ineficiente de los recursos de la CPU, por lo que el búfer intermedio se usa para acumular algunas solicitudes y luego llamar al sistema operativo con una sola solicitud.

Por lo tanto, cin::ignore puede descartar los bytes sobrantes en el búfer que pueden leerse accidentalmente cuando hay llamadas consecutivas. El siguiente código de ejemplo está diseñado para demostrar el comportamiento ignorar más claramente. Implementamos un bucle infinito while que lee tres enteros del flujo cin y los almacena en las variables correspondientes. Los enteros se imprimen en cout y luego la rutina se ejecuta en la siguiente iteración. Tenga en cuenta que el usuario puede proporcionar más de tres números enteros en la primera iteración. En ese caso, el código antes de cin.ignore almacenaría sólo 3 de ellos, y otros seguirían existiendo en un búfer intermedio. Ahora, si no se llama a cin.ignore con los parámetros dados, la siguiente línea de iteración cin >> leerá el resto de la entrada y se producirá el comportamiento inconsistente. La llamada cin.ignore se puede utilizar en tales escenarios para descartar la entrada hasta que no se encuentre el carácter dado. En este caso, especificamos un carácter de nueva línea que generalmente se usa para almacenar en búfer el flujo cin.

#include <iostream>
#include <limits>
#include <sstream>

using std::cin;
using std::cout;
using std::endl;
using std::numeric_limits;

int main() {
  while (true) {
    int i1, i2, i3;
    cout << "Type space separated numbers: " << endl;
    cin >> i1 >> i2 >> i3;
    if (i1 == 0) exit(EXIT_SUCCESS);
    cin.ignore(numeric_limits<std::streamsize>::max(), '\n');
    cout << i1 << "; " << i2 << "; " << i3 << endl;
  }

  return EXIT_SUCCESS;
}

Salida (con la entrada del usuario de muestra):

Type space separated numbers:
12 32 54
12; 32; 54

Alternativamente, podemos implementar otro código de ejemplo que tome dos cadenas divididas por un delimitador de caracteres de espacio. En este escenario, existe la posibilidad de que el usuario proporcione más de 2 nombres, lo que obligaría a este código a eliminar todas las iniciales después de 2 cadenas separadas por espacios. Si solo hay un nombre y un espacio en la entrada del usuario, entonces un carácter de nueva línea, que siempre termina la entrada cin, se almacenará como la segunda inicial. Este último comportamiento se puede demostrar agregando la salida de un solo carácter después de la declaración << name << surname.

#include <iostream>
#include <limits>
#include <sstream>

using std::cin;
using std::cout;
using std::endl;
using std::numeric_limits;

int main() {
  char name, surname;
  cout << "Type your name and surname: ";
  name = cin.get();
  cin.ignore(numeric_limits<std::streamsize>::max(), ' ');
  surname = cin.get();

  cout << "Your initials are: " << name << surname << endl;

  return EXIT_SUCCESS;
}

Salida (con la entrada del usuario de muestra):

Type your name and surname: Lama Lime
Your initials are: LL
``
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Artículo relacionado - C++ IO