Como faço para limpar o buffer cin?


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.


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')

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');
}

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!


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";


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.


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.


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.


1

O seguinte deve funcionar:

cin.flush();

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

cin.ignore(INT_MAX);

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)

0

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


0

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

cin.ignore()
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.