IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

[Debutant] Try-Catch général


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de cs_ntd
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2006
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2006
    Messages : 598
    Par défaut [Debutant] Try-Catch général
    Bien boujour à tous,

    Je débute en C++, et j'aimerais faire un Try{} Catch(){}, mais je n'arrive pas à trouver d'informations concluantes sur mon problème...

    Voici le principe de ce que je veux faire :

    Une invite apparait sur un terminal. L'utilisateur répond à la question posée.

    exemple:.

    Dans mon code, et dans le cas où l'utilisateur rentre effectivement un nombre, je souhaite rentrer cette valeur dans une variable de type int.
    J'ai pensé à celà:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int ans;
    ...
    std::cin >> ans;
    .

    Si jamais la réponse n'est PAS du bon type, je souhaite réafficher l'invite. Voici le code auquel j'ai pensé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    int ans;
    bool pass=false;
     
    while(!pass)
    {
       try
       {
          std::cout << "INT";
          std::cin >> ans;
          pass=true;
     
       }
       catch(...)
       {
          pass=false;
       }
    }
    Malheureusement, ce code n'a pas l'air de lever d'exeptions, et on ne passe apparement pas par le block catch(...).

    Je n'ai pas de "plantage" apparent, et j'obtiens des résultats très étranges dans le suite de l'execution (par exemple affichage de tous les "std::cout" suivant ).
    Je ne comprend pas trop ce qui se passe, étant donné que mon programme cesse de s'exectuer normalement, mais sans lever d'exeption...


    Voici le code exact de mon programme de test, ainsi que les résultats :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    #include <iostream>
    using namespace std;
     
    int main(void)
    {
       bool pass=false;
       int ans;
       string ans2;
       bool ans3;
       double ans4;
       char ans5[50];
     
       while(!pass)
       {
          try
          {
             cout << "INT";
             cin >> ans;
             pass=true;
             cout << "OK";
          }
          catch(...)
          {
             pass=false;
             cout << "ERREUR!!!";
          }
          cout << pass;
       }
       cout << "STRING";
       cin >> ans2;
       cout << "BOOL";
       cin >> ans3;
       cout << "DOUBLE";
       cin >> ans4;
       cout << "CHAR[]";
       cin >> ans5;
     
       return 0;
    }
    Résultats :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    name@machine:~$ ./Test
    INT=m  //ma réponse (à un type attendu int): un caractère 'm'
    1OKSTRING=BOOL=DOUBLE=CHAR[]=name@machine:~$
    Quelqu'un a-t-il une idée de ce qui se passe ?

    Merci d'avance

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 117
    Billets dans le blog
    148
    Par défaut
    Bonjour,

    Je crois que votre problème à ça solution dans la FAQ C++ à propos du cin et de la vérification du type.

    Le cin, lorsqu'il ne peut récupéré le bon champs, ne lance pas d'execution, donc votre programme va continuer tranquillement son travail.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Aucune exception n'est lancée en cas d'erreur sur le flux
    Il faut tester correctement ce dernier, et effectivement, la réponse est dans la FAQ.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  4. #4
    Membre éclairé Avatar de cs_ntd
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2006
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2006
    Messages : 598
    Par défaut


    Merci à tous !

    Effectivement, la réponse était dans la FAQ, mais je situais plus mon problème dans le try/catch (j'étais vraiment persuadé que ça déclancherais une exception ! L'habitude des langages trop haut niveau peut-être ).

    En plus j'ai cherché une fonction retournant le type d'un objet, mais je n'ais bien sur rien trouvé non plus à ce sujet, le point clé étant sur le booléen retourné par cin >> var...

    Et merci aussi koala01 pour ces exemples, ça aide . Il ne reste que cette histoire de buffer qui reste assez obscure pour moi, mais bon ça ne me sert pas trop pour le moment... ( et puis faut bien garder une part de mystère ).


    Par contre, j'aimerais beaucoup comprendre pourquoi l'execution du programme a continué à moitié... Càd en affichant sur le terminal tous mes std::cout "prompt" suivants, mais en oubliant mes std::cin qui devraient normalement pauser l'execution...
    (name@machine:~$ ./Test
    INT=m //ma réponse (à un type attendu int): un caractère 'm'
    1OKSTRING=BOOL=DOUBLE=CHAR[]=name@machine:~$ )
    Parceque là, pour reprendre LittleWhite, mon programme ne continue pas son travail tranquillement du tout !
    Bon à tous les coups c'est une histoire de buffer non-purgé je suis sûr
    Même si je vois pas du tout ce qui peux se passer...........

    En tous cas, merci encore de votre aide

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    En deux mots, c'est normal...

    cin ne lance aucune exception si, pour ton plus grand malheur, la valeur introduite par l'utilisateur ne correspond pas, en type à la valeur que tu souhaite obtenir.

    Par contre, tu dispose d'un opérateur de conversion implicite en booléen afin de savoir si la saisie s'est effectivement correctement déroulée.

    Tu as donc deux solutions:
    Soit, tu t'arrange pour lancer toi-même une exception si la saisie ne correspond pas à ce qui est attendu
    • Soit, une saisie ne correspondant pas au type attendu n'étant définitivement pas un cas d'exception avec tout ce que cela comporte (nécessité de "remonter" la pile d'appel afin d'apporter une (partie de la solution), tu ne gère purement et simplement pas ce problème sous la forme d'une exception
    La deuxième solution semble clairement plus adaptée, et pourrait prendre la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    int main()
    {
        int i;
        cout<<"introduisez un nombre :";
        while(!(cin>>i))  // vaudra false si la  valeur introduite n'est pas 
                          // un entier
        {
            if(cin.fail()) // si la  saisie a échoué, on engueule l'imbécile
                           // distrait qui n'a pas compris ce qu'on lui demande
                           // et on répète ce que l'on attend de lui
            {
                cout<<"j'ai demandé un nombre entier..."<<endl;
                cout<<"introduisez un nombre :";
                // on remet les bits d'erreur à 0
                cin.clear();
                // et on vide le buffer de cin de tout ce qu'il contient
                cin.ignore( numeric_limits<streamsize>::max(), '\n' );
     
            }
     
        }
        // on a fini par l'avoir, notre entier, on l'affiche
        cout<<"vous avez introduit "<<i<<endl;
        return 0;
    }
    Si tu veux "jouer" avec les exceptions, cela prendrait une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    /* tant qu'à faire, créons une exception particulière :D */
    struct NotANumber
    {
       /* ce sera elle qui se chargera d'engueuler l'imbécile distrait
        * qui n'a pas compris ce qu'on attend de lui
        */
        char const * what()const {return "j'ai demandé un nombre entier...";}
     
    };
    int main()
    {
        bool ok=false;
        int i;
        do
        {
            try
            {
                cout<<"introduisez un entier :";
                if(!(cin>>i))
                    throw NotANumber();
                ok=true;
            }
            catch(NotANumber const & e)
            {
                /* si on a attrapé une exception:
                 * 1 - on affiche le message correspondant
                 * 2 - on remet les bits d'erreur de cin à 0
                 * 3 - on purge le buffer de cin
                 */
                cout<<e.what()<<endl;
                cin.clear();
                cin.ignore( numeric_limits<streamsize>::max(), '\n' );
            }
     
        }while(!ok);
        // on a fini par l'avoir, notre entier, on l'affiche
        cout<<"vous avez introduit "<<i<<endl;
        return 0;
    }
    évidemment, ce code est très vite fait, et mériterait sans doute d'être amélioré
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Citation Envoyé par koala01 Voir le message
    évidemment, ce code est très vite fait, et mériterait sans doute d'être amélioré
    D'où la FAQ qui ne part pas en boucle infinie sur une coupure du flux d'entrée.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  7. #7
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    D'où la FAQ qui ne part pas en boucle infinie sur une coupure du flux d'entrée.
    Je ne pars pas non plus en boucle infinie

    Ca, j'ai quand même testé
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 11
    Dernier message: 18/09/2006, 17h23
  2. [DEBUTANT] Try catch
    Par flzox dans le forum Langage
    Réponses: 4
    Dernier message: 24/01/2006, 00h47
  3. [debutant sous eclipse] surround with try catch
    Par Alwin dans le forum Eclipse Java
    Réponses: 3
    Dernier message: 26/06/2004, 20h03
  4. [try-catch] relancer les instruction du bloc try
    Par nounou dans le forum Langage
    Réponses: 11
    Dernier message: 12/05/2004, 11h23
  5. Exception & Try..catch
    Par PurL dans le forum C++Builder
    Réponses: 2
    Dernier message: 11/12/2002, 15h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo