Como faço para limpar o buffer cin?

110

Como eu limpo o buffer cin em C ++?

Dana the Sane
fonte

Respostas:

101

Possivelmente:

std::cin.ignore(INT_MAX);

Isso iria ler e ignorar tudo até EOF . (você também pode fornecer um segundo argumento que é o caractere a ser lido até (ex: '\n'para ignorar uma única linha).

Além disso: você provavelmente também deseja fazer um: std::cin.clear();antes disso para redefinir o estado do fluxo.

Evan Teran
fonte
10
(Antigo eu sei.) Antes, claro, de modo que o fluxo seja colocado em um bom estado onde possa operar em seu buffer.
GManNickG,
Obrigado, GMan! Fiz da maneira errada, primeiro, e passei um bom tempo procurando meu erro.
balu
@GManNickG, acabou de corrigir a resposta.
bwDraco
@DragonLord: Uma solução óbvia que eu deveria ter feito em retrospecto, obrigado. :)
GManNickG
3
Só queria salientar que, para o meu caso, acho o '\ n' necessário. Caso contrário, o "cin >>" subsequente não funcionará.
Cardin
114

Eu preferiria as restrições de tamanho C ++ em vez das versões 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
fonte
15
Mais importante ainda, os valores podem ser diferentes! (o tamanho do fluxo não precisa ser int)
2
você poderia citar um exemplo em que precisamos ignorar até o final do arquivo porque se eu usar cine usar a primeira instrução acima para liberar o cinbuffer, ele continuará solicitando a entrada até que eu entre EOFpressionando ctrl+d?
domingo,
@ajay: Não. Isso é algo que você precisa decidir. Estou apenas explicando o que o que foi dito acima fará.
Martin York
23
cin.clear();
fflush(stdin);

Esta foi a única coisa que funcionou para mim ao ler do console. Em todos os outros casos, ele seria lido indefinidamente devido à falta de \ n ou algo permaneceria no buffer.

EDIT: Eu descobri que a solução anterior piorou as coisas. ESTE, entretanto, funciona:

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

Eu encontrei duas soluções para isso.

O primeiro, e mais simples, é usar, std::getline()por exemplo:

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

... isso descartará o fluxo de entrada quando chegar a uma nova linha. Leia mais sobre esta função aqui .

Outra opção que descarta diretamente o stream é esta ...

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

Boa sorte!

Ben
fonte
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
fonte
5

E se:

cin.ignore(cin.rdbuf()->in_avail());
Martin York
fonte
3
a função in_avail () do streambuf não é confiável, e muitas implementações retornam apenas zero. Consulte: connect.microsoft.com/VisualStudio/feedback/details/509337/… gnu's libc ++ é semelhante
James Caccese
4

Eu prefiro:

cin.clear();
fflush(stdin);

Há um exemplo em que cin.ignore simplesmente não funciona, mas não consigo pensar nele no momento. Já faz um tempo que precisei usá-lo (com o Mingw).

No entanto, fflush (stdin) é um comportamento indefinido de acordo com o padrão. fflush () serve apenas para fluxos de saída. fflush (stdin) só parece funcionar como esperado no Windows (com CCG e MS compiladores pelo menos) como uma extensão para o padrão C .

Portanto, se você usá-lo, seu código não será portátil.

Consulte Usando fflush (stdin) .

Além disso, consulte http://ubuntuforums.org/showpost.php?s=9129c7bd6e5c8fd67eb332126b59b54c&p=452568&postcount=1 para obter uma alternativa.

Shadow2531
fonte
9
fflush (stdin); é um comportamento indefinido (na linguagem de programação C), explicitamente declarado em 7.18.5.2/2
Cubbi
1
+1 para fornecer um kludge válido e funcional. Algumas pessoas têm empregos, outras têm padrões.
Mikhail
5
@Mikhail: Seu trabalho deve incluir a escrita de código compatível com o padrão. Vou evitar o uso de qualquer coisa que você tenha escrito no futuro.
Ed S.
4

Outra solução possível (manual) é

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

Não consigo usar fflush ou cin.flush () com CLion, então isso foi útil.

Bobul Mentol
fonte
loop infinito para mim.
StarWind0
Ele está funcionando apenas se houver fim de linha, caso contrário, loop infinito
Bobul Mentol
2

Caminho mais fácil:

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

Ele apenas posiciona o ponteiro cin no final do fluxo stdin e cin.clear () limpa todos os sinalizadores de erro, como o sinalizador EOF.

Chaitanya Vaishampayan
fonte
1

O seguinte deve funcionar:

cin.flush();

Em alguns sistemas não está disponível e você pode usar:

cin.ignore(INT_MAX);
Gunnar Steinn
fonte
1
por que escrever um loop manualmente quando você pode dizer para ignorar os caracteres de leitura INT_MAX até atingir EOF (o valor padrão do segundo parâmetro).
Evan Teran
Gunnar, talvez seja melhor editar sua postagem para refletir isso, apenas no caso.
Dana the Sane
1
Até onde eu sei, o flushmétodo é apenas para saída e lida com caracteres já escritos.
Marc van Leeuwen de
cin.flush ():basic_istream<char>' has no member named 'flush'
eric
1
#include <stdio_ext.h>

e então usar a função

__fpurge(stdin)
techcomp
fonte
0

cin.get() parece liberá-lo automaticamente de maneira bastante estranha (embora provavelmente não seja preferido, já que isso é confuso e provavelmente temperamental).

GuestPerson001
fonte
0

Funcionou para mim Eu usei o loop for com getline ().

cin.ignore()
Amrit Malla
fonte