Limpando o buffer de entrada em C / C++
O que é um buffer?
Uma área de armazenamento temporário é chamada de buffer. Todos os dispositivos de entrada e saída padrão contêm um buffer de entrada e saída. Em C / C++ padrão, os streams são armazenados em buffer, por exemplo, no caso de entrada padrão, quando pressionamos a tecla no teclado, ela não é enviada ao seu programa, mas sim armazenada em buffer pelo sistema operacional até que o tempo seja atribuído a isso programa.
Como isso afeta a programação?
Em várias ocasiões, você pode precisar limpar o buffer indesejado para obter a próxima entrada no contêiner desejado e não no buffer da variável anterior. Por exemplo, no caso de C depois de encontrar "scanf()", se precisarmos inserir uma matriz de caracteres ou caractere, e no caso de C++, depois de encontrar a instrução "cin", exigimos inserir uma matriz de caracteres ou uma string, exigimos limpar o buffer de entrada ou então a entrada desejada é ocupada pelo buffer da variável anterior, não pelo contêiner desejado. Ao pressionar "Enter" (retorno de carro) na tela de saída após a primeira entrada, como o buffer da variável anterior foi o espaço para o novo contêiner (como não o limpamos), o programa pula a seguinte entrada de contêiner.
No caso de programação C
// C Code to explain why not
// clearing the input buffer
// causes undesired outputs
#include<stdio.h>
int main()
{
char str[80], ch;
// Scan input from user -
// GeeksforGeeks for example
scanf("%s", str);
// Scan character from user-
// 'a' for example
ch = getchar();
// Printing character array,
// prints “GeeksforGeeks”)
printf("%s\n", str);
// This does not print
// character 'a'
printf("%c", ch);
return 0;
}
Entrada:
GeeksforGeeks a
Saída:
GeeksforGeeks
No caso de C++
// C++ Code to explain why
// not clearing the input
// buffer causes undesired
// outputs
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int a;
char ch[80];
// Enter input from user
// - 4 for example
cin >> a;
// Get input from user -
// "GeeksforGeeks" for example
cin.getline(ch,80);
// Prints 4
cout << a << endl;
// Printing string : This does
// not print string
cout << ch << endl;
return 0;
}
Entrada:
4 GeeksforGeeks
Saída:
4
Em ambos os códigos acima, a saída não é impressa conforme desejado. A razão para isso é um buffer ocupado. O caractere “\ n” permanece lá no buffer e é lido como a próxima entrada.
Como isso pode ser resolvido?
No caso de C:
- Usando “while ((getchar())! = '\ N'); ” : Digitando“ while ((getchar())! = '\ N'); ” lê os caracteres do buffer até o final e os descarta (incluindo nova linha) e, usando-o após a instrução “scanf()”, limpa o buffer de entrada e permite a entrada no contêiner desejado.
// C Code to explain why adding
// "while ( (getchar()) != '\n');"
// after "scanf()" statement
// flushes the input buffer
#include<stdio.h>
int main()
{
char str[80], ch;
// scan input from user -
// GeeksforGeeks for example
scanf("%s", str);
// flushes the standard input
// (clears the input buffer)
while ((getchar()) != '\n');
// scan character from user -
// 'a' for example
ch = getchar();
// Printing character array,
// prints “GeeksforGeeks”)
printf("%s\n", str);
// Printing character a: It
// will print 'a' this time
printf("%c", ch);
return 0;
}
- Entrada:
GeeksforGeeks a
- Saída:
GeeksforGeeks a
- Usando "fflush (stdin)" : digitar "fflush (stdin)" após a instrução "scanf()" também limpa o buffer de entrada, mas o uso dele é evitado e é denominado como "indefinido" para o fluxo de entrada de acordo com o C++ 11 padrões.
No caso de C++:
- Usando “cin.ignore (numeric_limits::max(), '\ n'); ” : - Digitando“ cin.ignore (numeric_limits::max(), '\ n'); ” depois que a instrução “cin” descarta tudo no fluxo de entrada, incluindo a nova linha.
// C++ Code to explain how
// "cin.ignore(numeric_limits
// <streamsize>::max(),'\n');"
// discards the input buffer
#include<iostream>
// for <streamsize>
#include<ios>
// for numeric_limits
#include<limits>
using namespace std;
int main()
{
int a;
char str[80];
// Enter input from user
// - 4 for example
cin >> a;
// discards the input buffer
cin.ignore(numeric_limits<streamsize>::max(),'\n');
// Get input from user -
// GeeksforGeeks for example
cin.getline(str, 80);
// Prints 4
cout << a << endl;
// Printing string : This
// will print string now
cout << str << endl;
return 0;
}
- Entrada:
4 GeeksforGeeks
- Saída:
4 GeeksforGeeks
- Usando “cin.sync()”: digitar “cin.sync()” após a instrução “cin” descarta tudo o que resta no buffer. Embora “cin.sync()” não funcione em todas as implementações (de acordo com os padrões C++ 11 e acima).
// C++ Code to explain how " cin.sync();"
// discards the input buffer
#include<iostream>
#include<ios>
#include<limits>
using namespace std;
int main()
{
int a;
char str[80];
// Enter input from user
// - 4 for example
cin >> a;
// Discards the input buffer
cin.sync();
// Get input from user -
// GeeksforGeeks for example
cin.getline(str, 80);
// Prints 4
cout << a << endl;
// Printing string - this
// will print string now
cout << str << endl;
return 0;
}
- Entrada:
4 GeeksforGeeks
- Saída:
4
- Usando “cin >> ws”: Digitar “cin >> ws” após a instrução “cin” diz ao compilador para ignorar o buffer e também descartar todos os espaços em branco antes do conteúdo real da string ou array de caracteres.
// C++ Code to explain how "cin >> ws"
// discards the input buffer along with
// initial white spaces of string
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int a;
string s;
// Enter input from user -
// 4 for example
cin >> a;
// Discards the input buffer and
// initial white spaces of string
cin >> ws;
// Get input from user -
// GeeksforGeeks for example
getline(cin, s);
// Prints 4 and GeeksforGeeks :
// will execute print a and s
cout << a << endl;
cout << s << endl;
return 0;
}
- Entrada:
4 GeeksforGeeks
- Saída:
4 GeeksforGeeks
Este artigo é uma contribuição de Manjeet Singh . Se você gosta de GeeksforGeeks e gostaria de contribuir, você também pode escrever um artigo e enviá-lo para review-team@geeksforgeeks.org. Veja o seu artigo na página principal do GeeksforGeeks e ajude outros Geeks.
Escreva comentários se encontrar algo incorreto ou se quiser compartilhar mais informações sobre o tópico discutido acima.
As postagens do blog Acervo Lima te ajudaram? Nos ajude a manter o blog no ar!
Faça uma doação para manter o blog funcionando.
70% das doações são no valor de R$ 5,00...
Diógenes Lima da Silva