Récupérer d'une erreur de lecture sur un flux

Soyez le premier à donner votre avis sur cette source.

Snippet vu 6 379 fois - Téléchargée 30 fois

Contenu du snippet

Le langage C++, comme la plupart des langages de programmation contemporains, permet de lire et d'écrire de et sur des flux de données, ce qui lui permet d'abstraire les accès aux périphériques comme le clavier, la souris ou un écran console de la même manière que celle utilisée pour abstraire l'accès à un fichier.

Le flux en entrée le plus typique avec C++, surtout en début de formation, est l'objet permettant l'asbtraction de l'entrée standard et nommé std::cin. Cette rubrique utilisera std::cin comme référence mais pourrait s'appliquer à tout dérivé de std::istream (si cette dernière phrase ne vous dit rien, ce n'est sans doute qu'une question de temps).

Si on désire reprendre la lecture tant et aussi longtemps qu'une valeur à la fois valide et située entre les bornes n'aura pas été saisie, il faudra remettre le flux en entrée sur ses pattes à chaque erreur. En effet, une entrée intraduisible sur un flux d'entrée a deux conséquences:

elle met le flux en étant d'échec (la méthode fail() retourne true); et
le contenu impossible à traduire reste coincé dans le flux (au cas où on en aurait besoin).
Si on veut lire un entier, comme c'est le cas dans notre exemple, et si le contenu de std::cin est impossible à traduire en entier, alors:

il faut oublier l'échec lors de la traduction, ce qu'on fait en sollicitant la méthode clear() du flux; et
il faut vider le flux des données intraduisibles avant de poursuivre--ou, en d'autres termes, ignorer ce qui y traîne encore, à l'aide de la méthode ignore() du flux.

Source / Exemple :


#include <iostream> // std::cin, std::cout, std::endl

int main ()
{
   const int BORNE_MIN = 1,
             BORNE_MAX = 10;
   std::cout << "Entrez un entier se situant entre "
             << BORNE_MIN
             << " et "
             << BORNE_MAX
             << " inclusivement. Votre choix: ";
   int ValeurLue;
   while (!(std::cin >> ValeurLue) || ValeurLue < BORNE_MIN || ValeurLue > BORNE_MAX)
   {
      std::cin.clear ();  // on oublie l'échec et on poursuit
      std::cin.ignore (); // ignorer le contenu déjà lu
      std::cout << "Erreur. Je veux un entier se situant entre "
                << BORNE_MIN
                << " et "
                << BORNE_MAX
                << " inclusivement. Votre choix: ";
   }
   std::cout << "La valeur choisie est: "
             << ValeurLue
             << "; merci!"
             << std::endl;
}

A voir également

Ajouter un commentaire Commentaires
Messages postés
229
Date d'inscription
dimanche 14 septembre 2003
Statut
Membre
Dernière intervention
20 août 2014

vangeurmasker -> je n'aime pas utiliser using namespace std; car lorsqu'on utilise plusieurs namespace, bah ça n'améliore pas la lisibilité du code bien au contraire -__-

lacousine -> bon code, très intéresant comme approche :-) merci
Messages postés
99
Date d'inscription
mercredi 12 mai 2004
Statut
Membre
Dernière intervention
29 mars 2006

using namespace std; permet de supprimer les std:: et d'ameliorer la lisibilité du code

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.