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.