Partage
  • Partager sur Facebook
  • Partager sur Twitter

Redondance à cause de l'entrée d'un texte

Fonction du second degré

Anonyme
    10 février 2018 à 3:39:09

    /*************************************************\
    *              Fonction du second degre         *
    * NOM:    ARNONE                                 *
    * PRENOM: MATTEO                                 *
    * CLASSE: 5EI                                    *
    **************************************************/
    #include <iostream> //Declaration des deux librairies dont je vais avoir besoin
    #include <math.h>
    using namespace std;
    main()
    {
        cout<<"*************************************************************************************"<<endl; //Affichage plus agreable pour les yeux de l'utilisateur
        cout<<"*                                                                                   *"<<endl;
        cout<<"*     Bienvenue dans le programme de resolution d'une equation du second degre      *"<<endl;
        cout<<"*                                                                                   *"<<endl;
        cout<<"*************************************************************************************"<<endl;
        double a, b, c, d, x1, x2, x;
    g:
        cout<<"Veuillez entrer les valeurs de vos variables"<<endl<<endl;
        cout<<"Valeur de a: ";
        cin>>a; cout<<endl;
        cout<<"Valeur de b: ";
        cin>>b; cout<<endl;
        cout<<"Valeur de c: ";
        cin>>c; cout<<endl;
        if(a!=0){
        cout<<"Votre equation du second degre est : "; //Affichage ‡ l'Ècran de l'Èquation du second degrÈ
        cout<<a<<"x2";
        if(b>=0){
                cout<<'+'<<b<<'x';
                }
        else cout<<b<<'x';
        if(c>=0){
                cout<<'+'<<c<<endl;
                }
        else cout<<c<<endl;
                    d=b*b-4*a*c; //RÈsolution de l'Èquation avec l'affichage des rÈponses
                    if(d>0){
                            x1=((-b)+ (sqrt(d))/2*a);
                            x2=((-b)- (sqrt(d))/2*a);
                            cout<<"Les reponses sont "<<x1<<" et "<<x2<<endl<<endl;
                            }
                    if(d==0)
                            {
                            x=-b/a*a;
                            cout<<"Votre solution est "<<x<<endl<<endl;
                            }
                    if(d<0){
                            cout<<"Il n'y a pas de solutions, l'equation est impossible"<<endl<<endl;
                            }
        }
        if(a==0){
        cout<<"Votre equation du premier degre est "<<b<<'x'; //Affichage ‡ l'Ècran de l'equation du premier degrÈ
        if(c>=0){
                cout<<'+'<<c<<endl;
                }
        else cout<<c<<endl;
                x=-c/b; //RÈsolution de l'Èquation et affichage des solutions de cette derniËre
                cout<<"Votre solution est "<<x<<endl<<endl;
                }
        if(b==0){
                cout<<"Equation impossible car 0 est diviseur"<<endl<<endl;
                }
        if(b==0 && c==0){
                        cout<<"Equation impossible car 0 n'est pas divisible par 0"<<endl<<endl;
        }
        cout<<"Voulez-vous recommencer ?O/N"<<endl; //Permet a l'utilisateur, s'il le souhaite, de relancer le programme sans que la fenêtre ne se ferme, ce qui est un gain de temps
        char rep;
        cin>>rep;
        if(rep=='O'||rep=='o'||rep==0)goto g;
        else return 0;
    }
    


    Bonjour à tous, mon problème est que lorsque je rentre du texte dans un endroit où il est censé il y avoir un chiffre, mon programme commence à se répéter rapidement et ne s'arrête plus. Alors vous allez me dire : "oui mais t'as juste à mettre du texte casse pas les pieds". Oui c'est vrai mais pensez à la secrétaire blonde qui sait à peine comment fonctionne un ordi et qui va mettre la lettre O à la place d'un zéro donc j'aimerais simplement rajouter de la robustesse à mon programme. Voici mon programme : 

    -
    Edité par Anonyme 13 février 2018 à 18:12:58

    • Partager sur Facebook
    • Partager sur Twitter
      10 février 2018 à 4:31:55

      Salut,

      C'est normal: tu dois valider (ou, à tout le moins, t'assurer que la donnée a pu être extraite) les entrées que l'utilisateur peut faire, car:

      • s'il entre du texte au lieu d'une valeur numérique, tu ne sauras rien en faire
      • si le flux d'entrée (std::cin, dans le cas présent, mais le problème se pose aussi avec les fichiers texte) n'arrive pas à extraire la donnée que tu lui a demandé, il n'a pas d'autre choix que de refuser l'entrée en question et de se mettre en état d'erreur.

      Pas de bol, les flux sont dit "bufferisés", c'est à dire qu'il permettent de garder en mémoire les informations qu'il reçoivent jusqu'à ce qu'il soient en mesure de les traiter (c'est valable pour les flux d'entrée comme pour les flux de sortie ;) ). 

      Or, le fait que le flux se mette en état d'erreur n'a aucun effet sur les données que le flux a en mémoire: elles y sont, elles y restent, jusqu'à ce qu'elles puissent être "correctement traitées".

      De plus, tu te doutes surement que, si le flux est dans un état d'erreur, il ne fera absolument rien tant que l'on ne l'aura pas remis dans un état valide ;)

      Il y a donc deux choses à faire, si l'extraction d'une donnée échoue :

      1. remettre le flux dans un état valide, en utilisant la fonction membre clear(), et
      2. purger le buffer de la donnée inutilisable qu'il contient (et, par sécurité, de tout ce qu'il contient)  Cette entrée de la FAQ de Developpez t'indiquera comment faire

      Maintenant, quelques (nombreuses) remarques concernant ton code:

      1- Quand tu veux présenter ton code, utilise le bouton en forme de </> qui se trouve au-dessus à droite de la zone d'édition.  Cela permettra de le présenter d'une manière bien plus lisible, avec l'indentation (s'il y en a) et une coloration syntaxique qui facilite la lecture

      2- Un bon commentaire est un commentaire que tu n'écris pas.  On se doute bien que double a, b, c, d, x1, x2, x; déclare des variables, il n'y a aucun besoin de le préciser ;)

      3- En C++, on essaye de déclarer les variables au plus près de leur utilisation, cela facilite la compréhension

      4- Fut un temps (jusqu'au début des années 80, dirons nous ) où le moindre caractère que l'on rajoutait à du code coutait la peau des fesses, mais, maintenant, nous ne sommes absolument plus à 100 ni même 10 000 caractères de plus dans le code, d'autant plus que la plupart seront purement et simplement absents du code binaire que le compilateur va générer (en mode release, en tout cas)

      Essaye de respecter cette règle toute simple : une ligne == une instruction (ou la déclaration d'UNE SEULE variable)

      4bis - Dans le même ordre d'idée, essaye de choisir des noms (pour tes variables, mais aussi plus tard pour tes fonctions et tes types) qui indiquent clairement l'usage auquel elles sont destinées.  Cela permet de s'y retrouver bien plus facilement.

      Evidemment, s'il y a des conventions particulière, en fonction du domaine pour lequel tu développe ton application, il est toujours préférable de les utiliser ;)

      5- Je ne sais pas où tu as appris l'existence de goto, mais c'est une pure aberration qui pourrait tout aussi bien être supprimée du langage

      Utilise les boucles, on a un choix largement suffisant pour palier à tous les besoin, et cela t'éviteras de te retrouver, à termes, avec un code qui ressemble à un plat de spagetti ;)

      6- On n'utilise plus la directive using namespace std; depuis plus de vingt ans dans du nouveau code. Utilises les noms pleinement qualifiés (std::cout, std::cin, std::endl, ...) Une recherche sur le forum te permettra de comprendre pourquoi

      7- std::endl a pour effet de purger le buffer du flux de sortie.  Mais c'est fait, a priori, automatiquement, et, une fois qu'il est purgé, il n'y a nulle besoin de le purger une nouvelle fois ;)

      Sauf cas bien particulier, si tu veux simplement forcer le retour à la ligne, tu peux te contenter d'utiliser le caractère qui le permet, à savoir '\n'

      8- <iostream> ne déclare pas de bibliothèque (tu utilises la bibliothèque standard, mais std::cin, std::cout, std::endl sont ... des variables globales)

      9- Typiquement, quand ils sont fournis par la bibliothèque standard, les fichiers d'en-tête dont l'extension est .h sont des fichiers d'en-tête issus du langage C. 

      Or, les fichiers d'en-tête issus de la bibliothèque standard de C++ (comme iostream) ne comportent pas d'extension.  C'est pourquoi la bibliothèque standard propose des adaptations (à certains points de vue, du moins) des fichiers issus du C sous la forme de fichiers (sans extension) dont le nom commence systématiquement par c (comme cmath ou cstring) pour faire la différence entre ses fichiers propres et ceux qui viennent du C.

      De manière générale, on préférera utiliser ces fichiers cxxx plutôt que les fichiers issus du C (pour toute une série de raisons que je ne vais pas expliquer maintenant).

      • Partager sur Facebook
      • Partager sur Twitter
      Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
      Anonyme
        11 février 2018 à 12:57:43

        Tout d'abord, je suis surpris, la réponse est super complété ca me fait énormément plaisir. Pour les goto, j'en suis conscient que c'est mal même très mal mais mon professeur d'informatique  qu'o l'utilise alors que je lui ai dit que c'était beaucoup plus pratique d'utiliser la fonction While et que c'était mauvais d'utiliser goto et il a totalement approuvé ce que j'ai dit mais il veut qu'on l'utilise quand même.

        Ensuite, pour le fait de ne pas déclarer la bibliothèque <iostream>, je ne comprends pas bien et pour le ".h" sur CodeBlocks 8.02 ils le déclarent en tant qu'erreur.

        Mais aussi, pour les commentaires je ne sais pas où placer mes commentaires pour qu'is soient le plus efficients. Je pense que c'est tout et merci beaucoup pour la réponse claire car je débute en prog et j'aimerai en faire mon métier alors voilà. Un grand merci encore haha ;)

        • Partager sur Facebook
        • Partager sur Twitter
          11 février 2018 à 18:05:58

          Matteo Arnone a écrit:

          Tout d'abord, je suis surpris, la réponse est super complété ca me fait énormément plaisir. Pour les goto, j'en suis conscient que c'est mal même très mal mais mon professeur d'informatique  qu'o l'utilise alors que je lui ai dit que c'était beaucoup plus pratique d'utiliser la fonction While et que c'était mauvais d'utiliser goto et il a totalement approuvé ce que j'ai dit mais il veut qu'on l'utilise quand même.

          Ah, ces profs qui persistent à apprendre des conneries et, pire encore, à forcer les élèves à les utiliser tout en sachant que c'est mal, quelle plaie!!!

          J'avais un prof qui était tout le contraire: il nous avait menacé de nous faire passer par la fenêtre si on utilisait goto. Ca, au moins, c'était la bonne approche :D

          Ensuite, pour le fait de ne pas déclarer la bibliothèque <iostream>, je ne comprends pas

          Je t'ait dit: ce n'est pas une bibliothèque!!!

          Veille à utiliser les termes corrects!!!

          C'est un fichier d'en-tête fourni par la bibliothèque standard et, qui, comme tous les fichiers d'en-tête fournis par la bibliothèque standard, ne contiennent simplement pas d'extension .h (ou autre)

          et pour le ".h" sur CodeBlocks 8.02 ils le déclarent en tant qu'erreur.

          Ce n'est pas CodeBlocks, c'est le compilateur qui fait ca, et c'est normal:

          l'extension (.h, par exemple) fait partie intégrante du nom du fichier, bien que windows cache les extensions par défaut. Si bien que tu peux tout à fait avoir, dans le même dossier, deux fichiers portant un nom identique, mais ayant une extension différente (moi.jpg et moi.avi, par exemple, le premier étant une photo, le second un film) sans que cela ne pose de problème

          Mais, du coup, cela signifie que, si tu ajoute un ".h" au nom d'un fichier qui n'en comporte normalement pas, le compilateur ne peut faire qu'une seule chose: te dire qu'il ne l'a pas trouvé...

          Mais aussi, pour les commentaires je ne sais pas où placer mes commentaires pour qu'is soient le plus efficients.

          On va faire simple: tu n'en met pas...

          Si, pour une raison ou une autre, tu te dis qu'une partie de ton code n'est pas claire et qu'elle mérite un commentaire, la seule chose sensée à faire est de tenter de réécrire ce code de manière plus claire ;) . Le plus souvent, il "suffit" de choisir des noms (de type, de variable ou de fonction) plus explicites ;)

          Il y a -- bien évidemment, et pour être complet -- quelques exceptions. Mais comme il semble que tu n'en soit pas encore arrivé au stade de ton apprentissage où tu sera confronté à ces exceptions, je vais les garder pour "plus tard" ;)

          • Partager sur Facebook
          • Partager sur Twitter
          Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
          Anonyme
            11 février 2018 à 18:44:50

            /*************************************************\
            
            *              Fonction du second degre         *
            
            * NOM:    ARNONE                                 *
            
            * PRENOM: MATTEO                                 *
            
            * CLASSE: 5EI                                    *
            
            **************************************************/ 
            
            #include <iostream> //Declaration des deux librairies dont je vais avoir besoin
            
            #include <math.h>
            
            using namespace std;
            
            int main()
            
            {
            
                cout<<"*************************************************************************************"<<endl; //Affichage plus agreable pour les yeux de l'utilisateur
            
                cout<<"*                                                                                   *"<<endl;
            
                cout<<"*     Bienvenue dans le programme de resolution d'une equation du second degre      *"<<endl;
            
                cout<<"*                                                                                   *"<<endl;
            
                cout<<"*************************************************************************************"<<endl;
            
                double b, c, d, x1, x2, x;
            
                char a;
            
            g:
            
                cout<<"Veuillez entrer les valeurs de vos variables"<<endl<<endl;
            
                cout<<"Valeur de a: ";
            
                cin>>a; if(a>=65 && a<=90 && a>=97 && a<=122) cout<<"Erreur";
            
                cout<<"Valeur de b: ";
            
                cin>>b; cout<<endl;
            
                cout<<"Valeur de c: ";
            
                cin>>c; cout<<endl;
            
                if(a!=0){
            
                cout<<"Votre equation du second degre est : "; //Affichage ‡ l'Ècran de l'Èquation du second degrÈ
            
                cout<<a<<"x2";
            
                if(b>=0){
            
                        cout<<'+'<<b<<'x';
            
                        }
            
                else cout<<b<<'x';
            
                if(c>=0){
            
                        cout<<'+'<<c<<endl;
            
                        }
            
                else cout<<c<<endl;
            
                            d=b*b-4*a*c; //RÈsolution de l'Èquation avec l'affichage des rÈponses
            
                            if(d>0){
            
                                    x1=((-b)+ (sqrt(d))/2*a);
            
                                    x2=((-b)- (sqrt(d))/2*a);
            
                                    cout<<"Les reponses sont "<<x1<<" et "<<x2<<endl<<endl;
            
                                    }
            
                            if(d==0)
            
                                    {
            
                                    x=-b/a*a;
            
                                    cout<<"Votre solution est "<<x<<endl<<endl;
            
                                    }
            
                            if(d<0){
            
                                    cout<<"Il n'y a pas de solutions, l'equation est impossible"<<endl<<endl;
            
                                    }
            
                }
            
                if(a==0){
            
                cout<<"Votre equation du premier degre est "<<b<<'x'; //Affichage ‡ l'Ècran de l'equation du premier degrÈ
            
                if(c>=0){
            
                        cout<<'+'<<c<<endl;
            
                        }
            
                else cout<<c<<endl;
            
                        x=-c/b; //RÈsolution de l'Èquation et affichage des solutions de cette derniËre
            
                        cout<<"Votre solution est "<<x<<endl<<endl;
            
                        }
            
                if(b==0){
            
                        cout<<"Equation impossible car 0 est diviseur"<<endl<<endl;
            
                        }
            
                if(b==0 && c==0){
            
                                cout<<"Equation impossible car 0 n'est pas divisible par 0"<<endl<<endl;
            
                }
            
                cout<<"Voulez-vous recommencer ?O/N"<<endl; //Permet ‡ l'utilisateur, s'il le souhaite, de relancer le programme sans que la fenÍtre ne se ferme, ce qui est un gain de temps
            
                char rep;
            
                cin>>rep;
            
                if(rep=='O'||rep=='o'||rep==0)goto g;
            
                else return 0;
            
            }
             


            Un grand merci et pour la fonction clear() je ne trouve pas d'exemple concret. Saurais-tu m'en passer un s'il te plaît ? 
            Je ne sais pas comment exclure a si on rentre du texte. J'ai voulu déclarer a en tant que variable de type char et d'exclure les nombres valant des lettres minuscules et majuscules mais je n'ai pas réussi. Voilà ce que j'ai essayé de faire.

            Je sais que ça peut paraître complètement idiot mais je ne sais vraiment pas comment exclure ça et pour tout te dire c'est un travail que je dois rendre et j'ai envie qu'il soit le plus robuste possible.  

            PS: je n'ai pas encore apporté toutes les modifications que tu m'as citée telle que using namespace std;

            -
            Edité par Anonyme 13 février 2018 à 18:15:36

            • Partager sur Facebook
            • Partager sur Twitter
              11 février 2018 à 18:50:13

              Ben, pour faire simple:
              int i;
              if(! std::cin>>i){
                  // 1- remet l'entrée standard dans un état valide
                  std::cin.clear(); 
                  /* 2- vide le tampon de l'entrée standard de tout
                   * ce qu'il peut contenir
                   */
                  std::cin.ignore(std::numeric_limits<
                       std::streamsize>::max(), '\n';
              }

              PS: pourrais tu modifier ton message en utilisant le bouton en forme de </> qui se trouve au dessus à droite de la zone d'édition pour afficher ton code. Cela permettra de le rendre bien plus facile à lire ;)

              -
              Edité par koala01 11 février 2018 à 18:51:44

              • Partager sur Facebook
              • Partager sur Twitter
              Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
              Anonyme
                13 février 2018 à 18:21:32

                /*************************************************\
                *              Fonction du second degre         *
                * NOM:    ARNONE                                 *
                * PRENOM: MATTEO                                 *
                * CLASSE: 5EI                                    *
                **************************************************/
                #include <iostream> //Declaration des deux librairies dont je vais avoir besoin
                #include <math.h>
                using namespace std;
                int main()
                {
                    cout<<"*************************************************************************************"<<endl; //Affichage plus agreable pour les yeux de l'utilisateur
                    cout<<"*                                                                                   *"<<endl;
                    cout<<"*     Bienvenue dans le programme de resolution d'une equation du second degre      *"<<endl;
                    cout<<"*                                                                                   *"<<endl;
                    cout<<"*************************************************************************************"<<endl;
                    double a, b, c, d, x1, x2, x;
                g:
                    cout<<"Veuillez entrer les valeurs de vos variables"<<endl<<endl;
                    cout<<"Valeur de a: ";
                    cin>>a; if(!(cin>>a)){
                        cin.clear();
                        std::cin.ignore(std::numeric_limits<std::streamsize>::max();
                    }
                    cout<<"Valeur de b: ";
                    cin>>b; cout<<endl;
                    cout<<"Valeur de c: ";
                    cin>>c; cout<<endl;
                    if(a!=0){
                    cout<<"Votre equation du second degre est : "; //Affichage ‡ l'Ècran de l'Èquation du second degrÈ
                    cout<<a<<"x2";
                    if(b>=0){
                            cout<<'+'<<b<<'x';
                            }
                    else cout<<b<<'x';
                    if(c>=0){
                            cout<<'+'<<c<<endl;
                            }
                    else cout<<c<<endl;
                                d=b*b-4*a*c; //RÈsolution de l'Èquation avec l'affichage des rÈponses
                                if(d>0){
                                        x1=((-b)+ (sqrt(d))/2*a);
                                        x2=((-b)- (sqrt(d))/2*a);
                                        cout<<"Les reponses sont "<<x1<<" et "<<x2<<endl<<endl;
                                        }
                                if(d==0)
                                        {
                                        x=-b/a*a;
                                        cout<<"Votre solution est "<<x<<endl<<endl;
                                        }
                                if(d<0){
                                        cout<<"Il n'y a pas de solutions, l'equation est impossible"<<endl<<endl;
                                        }
                    }
                    if(a==0){
                    cout<<"Votre equation du premier degre est "<<b<<'x'; //Affichage ‡ l'Ècran de l'equation du premier degrÈ
                    if(c>=0){
                            cout<<'+'<<c<<endl;
                            }
                    else cout<<c<<endl;
                            x=-c/b; //RÈsolution de l'Èquation et affichage des solutions de cette derniËre
                            cout<<"Votre solution est "<<x<<endl<<endl;
                            }
                    if(b==0){
                            cout<<"Equation impossible car 0 est diviseur"<<endl<<endl;
                            }
                    if(b==0 && c==0){
                                    cout<<"Equation impossible car 0 n'est pas divisible par 0"<<endl<<endl;
                    }
                    cout<<"Voulez-vous recommencer ?O/N"<<endl; //Permet a l'utilisateur, s'il le souhaite, de relancer le programme sans que la fenêtre ne se ferme, ce qui est un gain de temps
                    char rep;
                    cin>>rep;
                    if(rep=='O'||rep=='o'||rep==0)goto g;
                    else return 0;
                }
                

                Voici ce que ça me fait lorsque je change mon code. Que faire ?
                • Partager sur Facebook
                • Partager sur Twitter
                  13 février 2018 à 19:17:47

                  Tu n'as pas inclus le header <limits> qui permet d'utiliser std::numeric_limits, c'est ce qu'essaye de te faire comprendre le compilo en te disant qu'il ne connaît pas numeric_limits.

                  Pour ton problème de contrôle de saisie j'avais crée un petit header qui permettait de simplifier tout ça : >ici<, tu peux inclure .h et .cpp et l'utiliser tel quel (tout est expliqué) ou bien t'en inspirer.

                  En revanche je pense vraiment que tu devrais écouter les autres et enlever les goto, refaire l'indentation et utiliser cmath au lieu de math.h !

                  • Partager sur Facebook
                  • Partager sur Twitter
                  La flemme vaincra.
                  Anonyme
                    19 février 2018 à 13:38:30

                    Les goto je vais les enlever après le programme car le prof veut absolument mettre des goto même si on lui a dit qu'on préférait while.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      19 février 2018 à 14:23:18

                      using namespace std;

                      Il te reste également à bannir ceci.

                      Cette directive à été mise en place quand les espaces de noms ont été introduit en C++ (en 1990), et n'a pour seul et unique but que d'assurer la compatibilité avec les codes les plus anciens. Elle n'a rien à faire dans un code moderne.

                      - Soit tu qualifies pleinement les appels des fonctions avec l'espace de nom, suivit de l'operateur de résolution de portée, suivit du nom de la fonction.
                      - Soit tu selectionne précisément ce dont tu as besoin.

                      Exemples:

                      #include <iostream>
                      
                          // qualifier pleinement les appels de fonction
                      int main()
                      {
                          std::cout << "Hello world." << std::endl;
                      }
                      #include <iostream>
                      
                          // Ne selectionner que ce dont on a besoin
                      int main()
                      {
                          using std::cout;
                          using std::endl;
                      
                          cout << "Hello world." << endl;
                      }




                      • Partager sur Facebook
                      • Partager sur Twitter

                      Redondance à cause de l'entrée d'un texte

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                      • Editeur
                      • Markdown