Comment vider le tampon cin?

110

Comment effacer le tampon cin en C ++?

Dana le sain d'esprit
la source

Réponses:

101

Peut-être:

std::cin.ignore(INT_MAX);

Cela lirait et ignorerait tout jusqu'à ce que EOF. (vous pouvez également fournir un deuxième argument qui est le caractère à lire jusqu'à (ex: '\n'ignorer une seule ligne).

Aussi: vous voudrez probablement faire un: std::cin.clear();avant cela aussi pour réinitialiser l'état du flux.

Evan Teran
la source
10
(Vieux je sais.) Effacer avant, plutôt, donc le flux est mis dans un bon état où il peut fonctionner sur son tampon.
GManNickG
Merci GMan! Je l'ai fait dans le mauvais sens, d'abord, et j'ai passé un certain temps à chercher mon erreur.
balu
@GManNickG, vient de corriger la réponse.
bwDraco
@DragonLord: Solution évidente que j'aurais dû faire avec le recul, merci. :)
GManNickG
3
Je voulais juste souligner que pour mon cas, je trouve le '\ n' nécessaire. Sinon, "cin >>" ne fonctionnera pas.
Cardin
114

Je préférerais les contraintes de taille C ++ aux versions 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
la source
15
Plus important encore, les valeurs peuvent être différentes! (streamsize n'a pas à être int)
2
pourriez-vous s'il vous plaît citer un exemple où nous devons ignorer jusqu'à la fin du fichier parce que si j'utilise cinet utilise la première instruction ci-dessus pour vider le cintampon, alors il continue à demander une entrée jusqu'à ce que j'entre EOFen appuyant sur ctrl+d?
ajay
@ajay: Non. C'est quelque chose que vous devrez décider. J'explique simplement ce que fera ce qui précède.
Martin York
23
cin.clear();
fflush(stdin);

C'était la seule chose qui fonctionnait pour moi lors de la lecture depuis la console. Dans tous les autres cas, il serait lu indéfiniment en raison du manque de \ n, ou quelque chose resterait dans le tampon.

EDIT: J'ai découvert que la solution précédente a aggravé les choses. Celui-ci fonctionne cependant:

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

J'ai trouvé deux solutions à cela.

Le premier, et le plus simple, consiste à utiliser std::getline()par exemple:

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

... cela rejettera le flux d'entrée lorsqu'il atteindra une nouvelle ligne. En savoir plus sur cette fonction ici .

Une autre option qui rejette directement le flux est la suivante ...

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

Bonne chance!

Ben
la source
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
la source
5

Que diriez-vous:

cin.ignore(cin.rdbuf()->in_avail());
Martin York
la source
3
la fonction in_avail () de streambuf n'est pas fiable et de nombreuses implémentations renvoient simplement zéro. Voir: connect.microsoft.com/VisualStudio/feedback/details/509337 / ... la libc ++ de gnu est similaire
James Caccese
4

Je préfère:

cin.clear();
fflush(stdin);

Il y a un exemple où cin.ignore ne le coupe tout simplement pas, mais je ne peux pas y penser pour le moment. Il y a quelque temps, j'avais besoin de l'utiliser (avec Mingw).

Cependant, fflush (stdin) est un comportement non défini selon la norme. fflush () est uniquement destiné aux flux de sortie. fflush (stdin) ne semble fonctionner comme prévu sur Windows (avec les compilateurs GCC et MS au moins) comme une extension à la norme C .

Donc, si vous l'utilisez, votre code ne sera pas portable.

Voir Utilisation de fflush (stdin) .

Voir également http://ubuntuforums.org/showpost.php?s=9129c7bd6e5c8fd67eb332126b59b54c&p=452568&postcount=1 pour une alternative.

Ombre2531
la source
9
fflush (stdin); est un comportement indéfini (dans le langage de programmation C), explicitement déclaré ainsi dans 7.18.5.2/2
Cubbi
1
+1 pour fournir un kludge valide et fonctionnel. Certaines personnes ont des emplois, d'autres ont des normes.
Mikhail
5
@Mikhail: Votre travail doit inclure l'écriture de code conforme aux normes. Je veillerai à éviter d'utiliser tout ce que vous avez écrit à l'avenir.
Ed S.
4

Une autre solution (manuelle) possible est

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

Je ne peux pas utiliser fflush ou cin.flush () avec CLion, c'est donc très pratique.

Bobul Mentol
la source
boucle infinie pour moi.
StarWind0
Cela ne fonctionne que s'il y a une fin de ligne, sinon une boucle infinie
Bobul Mentol
2

Moyen le plus simple:

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

Il positionne simplement le pointeur cin à la fin du flux stdin et cin.clear () efface tous les indicateurs d'erreur tels que l'indicateur EOF.

Chaitanya Vaishampayan
la source
1

Les éléments suivants devraient fonctionner:

cin.flush();

Sur certains systèmes, il n'est pas disponible et vous pouvez alors utiliser:

cin.ignore(INT_MAX);
Gunnar Steinn
la source
1
pourquoi écrire manuellement une boucle alors que vous pouvez dire ignorer les caractères INT_MAX lus jusqu'à ce qu'il atteigne EOF (la valeur par défaut du deuxième paramètre).
Evan Teran
Gunnar, il serait peut-être préférable de modifier votre message pour refléter cela, au cas où.
Dana the Sane
1
Pour autant que je sache, la flushméthode est pour la sortie uniquement et traite des caractères déjà écrits.
Marc van Leeuwen
cin.flush ():basic_istream<char>' has no member named 'flush'
eric
1
#include <stdio_ext.h>

puis utilisez la fonction

__fpurge(stdin)
techcomp
la source
0

cin.get() semble le vider automatiquement assez curieusement (probablement pas préféré, car cela est déroutant et probablement capricieux).

GuestPerson001
la source
0

Cela a fonctionné pour moi. J'ai utilisé une boucle for avec getline ().

cin.ignore()
Amrit Malla
la source