2017-08-20 2 views
-3

J'ai une question à propos de C++. J'ai cherché une réponse et n'ai trouvé rien qui puisse réparer mon code. J'ai donc décidé de me demander. Mon problème est, que j'ai fait ce petit programme qui sortira le jour de la semaine, donc si l'utilisateur entre 1, il sortira le 1er jour de la semaine (dimanche ou lundi, dépend de l'endroit où vous vivez) et ainsi de suite ainsi de suite. Toutefois, si l'utilisateur entre par exemple, 8, le programme affichera "Veuillez choisir un nombre entre 1 et 7!" Cependant, mon problème est que lorsque l'utilisateur entre un caractère ou un mot aléatoire, il va boucler "S'il vous plaît choisir un nombre entre 1 et 7!" pour toujours.C++ Cin ignore les non-entiers?

#include <iostream> 
#include <Windows.h> 
#include <string> 
using namespace std; 


int main() { 

    int input; 


    do { 
     cin >> input; 
     switch (input) { 
     case 1: 
      cout << "Sunday" << endl; 
      break; 
     case 2: 
      cout << "Monday" << endl; 
      break; 
     case 3: 
      cout << "Tuesday" << endl; 
      break; 
     case 4: 
      cout << "Wednesday" << endl; 
      break; 
     case 5: 
      cout << "Thursday" << endl; 
      break; 
     case 6: 
      cout << "Friday" << endl; 
      break; 
     case 7: 
      cout << "Saturday" << endl; 
      break; 
     default: 
      cout << "Please choose a number between 1 and 7!" << endl; // if user chooses a number not from 1-7 output this. But if input is not an int and for example "a", it will loop this forever. 
      break; 
     } 

    } while (true); 


    return 0; 
} 
+0

C'est normal. Vous ne vérifiez jamais si 'cin >> entrée;' OK. – user0042

Répondre

0

Les opérations d'E/S définissent des indicateurs sur l'état actuel du flux.

Ce sont des indicateurs importants, ce que vous devez prendre soin au sujet si la lecture entrée

  • badbit - Erreur de lecture/écriture sur i/o opération
  • failbit - Erreur logique sur i/o opération
  • eofbit - fin de fichier atteint sur le fonctionnement d'entrée

Si vous passez un caractère ruisseau qui attend int (passer un mauvais type de données global, qui ne peut être converti en tapez que cin attend), le failbit est défini.

C'est la raison pour laquelle vous êtes entré dans une boucle infinie après avoir inséré une mauvaise entrée. failbit a été défini et cin n'a pas été effacé, donc l'opération de lecture suivante a échoué aussi bien et encore et encore.

La chose à faire est de mettre à failbit et d'éliminer la mauvaise entrée du tampon d'entrée en utilisant ignore.

std::cin.clear();  // without params clears flags 
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Clear input buffer 

std::cin.fail() vous dira si failbit est réglé (mauvais fonctionnement IO).

int input; 
cin >> input; 
while (! cin.fail()) 
{ 
    // Process data 
    cin >> input; 
} 

et std::cin.eof() vous dira si eofbit est réglé, atteindre EOF (CTRL + D/+ Z sur l'entrée std)

if (cin.eof()) 
{ 
    // End of file (input) reached 
    // Terminate reading 
} 
0

Déclaration cin >> input peut échouer, par exemple si un utilisateur entre quelque chose qui ne peut pas être converti en une valeur intégrale, ou si le flux atteint EOF (par exemple CTRL-D ou CTRL-Z en entrée standard). Si cin >> input échoue, deux choses se produisent: d'abord, un état d'erreur est défini, indiquant le type d'échec. Deuxièmement, l'expression renvoie false, indiquant qu'aucune valeur n'a été écrite dans input.

Donc, vous devriez toujours vérifier le résultat de cin >> ... avant d'aller de l'avant. Et, si vous détectez une entrée invalide, vous devrez réinitialiser le drapeau d'erreur (en utilisant cin.clear()) avant de le relire, et vous pouvez sauter l'entrée invalide (en utilisant cin.ignore(...)) afin d'éviter de lire dans le même (invalide) entrée encore et encore:

int main() { 

    int input; 
    while (true) { 

     while (!(cin >> input)) { 

      if (cin.eof()) { 
       cout << "user terminated input." << endl; 
       return 0; 
      } 
      cout << "invalid input (not a number); try again." << endl; 
      cin.clear(); 
      cin.ignore(numeric_limits<streamsize>::max(),'\n'); 
     } 

     // from here on, you may rely that the user has input a number. 

     cout << input; 

     // ... your code goes here 
    } 

    return 0 ; 
} 

Notez que vous devez spécifiquement permettre au programme de sortir en atteignant EOF.Sinon, vous pouvez exécuter une boucle infinie lorsque vous transmettez un fichier avec un contenu non valide en tant qu'entrée dans votre programme (par exemple, par myProgram < input.txt).