2010-02-13 5 views
4

Je voudrais que l'utilisateur entre un numéro de caractère central, par ex. Cependant, l'utilisateur peut entrer plus de 10.comment effacer le flux d'entrée inutile en C++

for(int i = 0 ; i< 10 ; i++) 
cin>>x; 

Le caractère supplémentaire pourrait faire planter mon code car je demanderai une saisie plus tard.

Comment puis-je effacer l'entrée à ce moment lorsque l'utilisateur entre plus de 10?

Merci beaucoup!

Répondre

0

Par ailleurs, pour éviter de dupliquer tout ce code à chaque fois, je une fois écrit une petite fonction de modèle pour faire ce travail:

template<typename InType> void AcquireInput(std::ostream & Os, std::istream & Is, const std::string & Prompt, const std::string & FailString, InType & Result) 
{ 
    do 
    { 
     Os<<Prompt.c_str(); 
     if(Is.fail()) 
     { 
      Is.clear(); 
      Is.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
     } 
     Is>>Result; 
     if(Is.fail()) 
      Os<<FailString.c_str(); 
    } while(Is.fail()); 
} 

template<typename InType> InType AcquireInput(std::ostream & Os, std::istream & Is, const std::string & Prompt, const std::string & FailString) 
{ 
    InType temp; 
    AcquireInput(Os,Is,Prompt,FailString,temp); 
    return temp; 
} 

La première surcharge peut être préférable si vous voulez éviter la copie, la deuxième peut être plus pratique pour les types intégrés. Exemples d'utilisation:

//1st overload 
int AnInteger; 
AcquireInput(cout,cin,"Please insert an integer: ","Invalid value.\n",AnInteger); 

//2nd overload (more convenient, in this case) 
int AnInteger=AcquireInput(cout,cin, "Please insert an integer: ","Invalid value.\n"); 
5
std::cin.clear(); 
    std::cin.ignore(std::numeric_limits<streamsize>::max(),'\n'); 

Cela devrait réinitialiser l'erreur et ignorer l'entrée défectueuse.

+0

streamsize est l'entrée? Que diriez-vous de la taille est dynamique en fonction d'autres variables? – skydoor

+0

'streamsize' est un type. 'cin.ignore()' prend deux arguments: le nombre maximum de caractères à ignorer (le type est 'streamsize'), et le délimiteur après lequel arrêter d'ignorer (le type est' char'). 'std :: numeric_limits :: max()' signifie "le plus grand nombre pouvant entrer dans une variable de type' streamsize'. Donc toute la ligne signifie "ignorer autant de caractères que nécessaire jusqu'à ce que vous ignoriez une nouvelle ligne, puis arrêtez. –

+0

... en supposant que la mauvaise entrée est le coupable ... – Potatoswatter

0

cin passe en mode erreur et arrête de faire quoi que ce soit si l'utilisateur donne une entrée invalide. Vous devez ajouter une vérification pour une entrée non valide et une boucle pour réessayer.

for(int i = 0 ; i< 10 ; i++) 
    while ((cin >> x).rdstate() == ios::failbit) { 
     cin.clear(); 
     cin.ignore(numeric_traits<streamsize>::max(), '\n'); 
    } 

C'est beaucoup de travail, mais vous devez définir une sorte de politique pour ignorer les entrées invalides. Il y a d'autres choix; cela ignore simplement le reste de la ligne.

0

Cela montre comment effacer toute la mémoire tampon sur une erreur.

de: http://support.microsoft.com/kb/132422

/* No special compile options needed. */ 

#include <iostream.h> 

int ClearError(istream& isIn)  // Clears istream object 
{ 
    streambuf* sbpThis; 
    char  szTempBuf[20]; 
    int   nCount, nRet = isIn.rdstate(); 

    if (nRet)      // Any errors? 
    { 
     isIn.clear();     // Clear error flags 
     sbpThis = isIn.rdbuf();  // Get streambuf pointer 
     nCount = sbpThis->in_avail(); // Number of characters in buffer 

     while (nCount)    // Extract them to szTempBuf 
     { 
      if (nCount > 20) 
      { 
       sbpThis->sgetn(szTempBuf, 20); 
       nCount -= 20; 
      } 
      else 
      { 
       sbpThis->sgetn(szTempBuf, nCount); 
       nCount = 0; 
      } 
     } 
    } 

    return nRet; 
} 

void main() 
{ 
    int n = 0, nState; 
    while (n <= 100) 
    { 
     cout << "Please enter an integer greater than 100.\n"; 
     cin >> n; 
     nState = ClearError(cin); // Clears any errors in cin 
    } 
}