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
``
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