Limpar buffer de entrada em C++

Jinku Hu 12 outubro 2023
Limpar buffer de entrada em C++

Este artigo demonstrará vários métodos de como limpar o buffer de entrada em C++.

Use a função std::cin::ignore para limpar o buffer de entrada em C++

ignore é uma função embutida do objeto std::cin, e pode ser usado para extrair e descartar caracteres do fluxo de entrada até o delimitador fornecido. Antes de discutirmos o comportamento da função cin::ignore, deve-se notar que os fluxos de entrada e saída padrão como cin / cout são armazenados em buffer, o que significa que há alguma contabilidade acontecendo entre as gravações / leituras do usuário e o estado real do buffer no kernel do sistema operacional. Esse buffer é gerenciado pela própria biblioteca C++ e seu objetivo é tornar as solicitações de leitura / gravação mais eficientes. Observe que chamar os serviços do sistema operacional para cada byte seria um uso bastante ineficiente dos recursos da CPU, portanto, o buffer intermediário é usado para acumular algumas solicitações e, em seguida, chamar o sistema operacional com uma única solicitação.

Assim, cin::ignore pode descartar bytes restantes no buffer que podem ser lidos acidentalmente quando há chamadas consecutivas. O código de exemplo a seguir foi projetado para demonstrar o comportamento ignore mais claramente. Implementamos um loop while infinito que lê três inteiros do fluxo cin e os armazena nas variáveis ​​correspondentes. Os inteiros são impressos no cout e então a rotina é executada na próxima iteração. Observe que o usuário pode fornecer mais de três inteiros na primeira iteração. Nesse caso, o código antes de cin.ignore armazenaria apenas 3 deles, e outros ainda existiriam em um buffer intermediário. Agora, se cin.ignore não for chamado com os parâmetros dados, a próxima iteração cin >> linha lerá o restante da entrada e o comportamento inconsistente ocorrerá. A chamada cin.ignore pode ser utilizada em tais cenários para descartar a entrada até que o caractere fornecido não seja encontrado. Neste caso, especificamos um novo caractere de linha que geralmente é usado para bufferizar o fluxo 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;
}

Saída (com a amostra de entrada do usuário):

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

Como alternativa, podemos implementar outro código de exemplo que leva duas strings divididas por um delimitador de caracteres de espaço. Nesse cenário, há uma chance de que o usuário forneça mais de 2 nomes, o que forçaria esse código a eliminar todas as iniciais após 2 strings separadas por espaço. Se houver apenas um nome e um espaço na entrada do usuário, um caractere de nova linha, que sempre termina a entrada cin, será armazenado como a segunda inicial. O último comportamento pode ser demonstrado adicionando a saída de um único caractere após a instrução << 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;
}

Saída (com a amostra de entrada do usuário):

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

Artigo relacionado - C++ IO