Partage
  • Partager sur Facebook
  • Partager sur Twitter

Petit problème de débutant

    12 septembre 2018 à 11:05:07

    Bonjour à tous,

    Je reprend la programmation et ne sais même pas comment nommer ce post. Comme on m'a souvent conseillé d'être curieux et d'essayer des choses par moi même et c'est ce que j'ai fais ce matin. Voici mon petit programme basique:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int age=0;
        double poids=0;
        printf("Donne moi ton age\nage: ");
        scanf("%d",&age);
        printf("\nMaintenant ton poids\npoids: ");
        scanf("%lf",&poids);
        printf("\nTu as donc %d ans et tu peses %f kilos",age,poids);
        return 0;
    }

    Quand on écrit l'âge avec seulement des chiffres tous cela se passe très bien, or quand on s'amuse à rajouter des lettres (16 ans par exemple), le programme saute le deuxième "scanf" et ne demande pas le poids à la personne, affichant ainsi seulement la phrase finale.

    Est ce que quelqu'un pourrai m'expliquer pourquoi il se passe cela, si oui comment faire pour que les lettres n'interfèrent pas avec mon programme ?

    Merci beaucoup, bonne journée :)

    • Partager sur Facebook
    • Partager sur Twitter
      12 septembre 2018 à 13:57:56

      Bonjour,

      C'est un problème de buffer le deuxième scanf va récupérer le reste de ta phrase qui est encore dans le buffer, je m'explique :

      Scanf attend un nombre entier, tu lui envoies "16 ans\n" et cela va être stocker dans le buffer, un espace memoire transitoire où le programme va venir chercher les informations que tu lui as fournis, du coup le premier scanf prends 16 et le deuxieme va prendre le reste de ta phrase car le buffer n'est pas vide !

      Il faut que tu vides ton buffer pour ne pas avoir ce genre de problème !

      • Partager sur Facebook
      • Partager sur Twitter
        12 septembre 2018 à 14:55:48

        sinon tu peux aussi regarder le retour de scanf()
        #include <stdio.h>
        #include <stdlib.h>
        
        int main()
        {
            int age=0;
            double poids=0;
            printf("Donne moi ton age\nage: ");
            while ( !scanf("%d",&age))
            { // si la saisie n'est pas valide
                while ( getchar() != '\n' ); // on vide le buffer
        
            }
        
            printf("\nMaintenant ton poids\npoids: ");
            while ( !scanf("%lf",&poids))
            { // si la saisie n'est pas valide
                while ( getchar() != '\n' ); // on vide le buffer
            }
        
            printf("\nTu as donc %d ans et tu peses %f kilos",age,poids);
            return 0;
        }
        
        en gros tant que tu mettra des lettre il videra le buffer et te redemanderas des chiffres

        -
        Edité par ox223252 12 septembre 2018 à 14:57:32

        • Partager sur Facebook
        • Partager sur Twitter

        la connaissance est une chose qui ne nous appauvrit pas quand on la partage.

        Mon GitHub

          13 septembre 2018 à 23:28:08

          Merci beaucoup à vous deux pour vos réponses,

          MrsSniperMrsniper j'ai regardé brièvement comment vider un buffer et il me semble que cela fait intervenir les fonctions, chose que j'avais vu auparavant mais dont je n'ai que peu de souvenirs. J'y viendrai par la suite mais je ne veux pas faire la même erreur que d'avancer trop vite sans avoir toutes les réponses à mes questions et avoir tout bien assimilé.

          En revanche quelque chose m'intrigue, quand je réponds à la question de l'âge par deux nombres espacer il va bien stocker ces deux nombres dans la mémoire vive, si je ne me trompe pas, et ressortir le premier pour l'âge et le deuxième pour le poids. Logique. En revanche quand je réponds "16ans" (sans espace) il saute bien le deuxième scanf, mais si j'écris 1653 il va stocker les 4 chiffres. Fais t-il donc la différence entre chiffre et lettre en faisant un "espace" lui même entre 16 et ans ? J'ai du mal à formuler ma question, j'espère que tu l'as comprise sinon je la reformulerai.

          ox223252très honnêtement je ne comprend pas exactement tout ^^, pour le ! j'ai trouvé comme seul traduction un NON, et je ne comprend donc pas ce que peux dire le !scanf, ni comment on peut vider un buffer en lui disant que tant que la saisi de caractère est différent d'un retour à la ligne :s je n'ai pas encore abordé toutes ces fonction donc j'ai un peu de mal à assimilé je comprendrai surement mieux dans quelques jours ou semaines!

          • Partager sur Facebook
          • Partager sur Twitter
            14 septembre 2018 à 7:45:19

            ThibaultRetourné a écrit:

            ox223252très honnêtement je ne comprend pas exactement tout ^^, pour le ! j'ai trouvé comme seul traduction un NON, et je ne comprend donc pas ce que peux dire le !scanf, ni comment on peut vider un buffer en lui disant que tant que la saisi de caractère est différent d'un retour à la ligne :s je n'ai pas encore abordé toutes ces fonction donc j'ai un peu de mal à assimilé je comprendrai surement mieux dans quelques jours ou semaines!


            alors je vais te donner quelques explications :

            scanf ( ) renvoie le nombre de variable lue, donc dans ce cas :

            scanf ( "%d", &age );

            il te renvoie 1 si tu à lu une variable numérique et 0 dans les autres cas ( genre des lettres ).

            Donc tant que tu écris des lettres ça te renvois zéro et avec l'inversion !, tu reste dans le while.

            Pour vider un buffer d'entré il faut lire son contenu (l'utilisation fflush() n'est pas la bonne solution), donc pour ce faire j'utilise getchar() qui lit 1 byte et tant que ce byte n'est pas un retour à la ligne alors il en reste donc on continue.

            -
            Edité par ox223252 14 septembre 2018 à 7:49:23

            • Partager sur Facebook
            • Partager sur Twitter

            la connaissance est une chose qui ne nous appauvrit pas quand on la partage.

            Mon GitHub

              14 septembre 2018 à 13:26:20

              D'accord, mais qu'est ce que ça change qu'il comprenne un caractère comme un 0 plutôt qu'un nombre comme un 1 ? J'ai essayé de mettre seulement une lettre au début et il zappe quand même la deuxième question pourtant une lettre ne peut pas prendre 2 places non ? :/
              • Partager sur Facebook
              • Partager sur Twitter
                14 septembre 2018 à 13:32:13

                non mais quand tu saisie une seule lettre tu saisie deux choses au clavier : <lettre><entrer> :-)

                EDIT : je suis pas sur d'avoir compris le début de ta phrase :

                > D'accord, mais qu'est ce que ça change qu'il comprenne un caractère comme un 0 plutôt qu'un nombre comme un 1 ?

                -
                Edité par ox223252 14 septembre 2018 à 13:34:19

                • Partager sur Facebook
                • Partager sur Twitter

                la connaissance est une chose qui ne nous appauvrit pas quand on la partage.

                Mon GitHub

                  14 septembre 2018 à 13:49:30

                  En fait, pour traiter correctement ces histoires (ce qu'aucun tutoriel ne fait, en réalité), il faut considérer que, dans un programme interactif question/réponse, l'utilisateur répond par une LIGNE de texte. Pas juste un caractère, un nombre, un mot. Une ligne.

                  Le programme doit alors

                  • lire une ligne COMPLETE (*)
                  • tenter d'en extraire les informations voulues (ça sera donc plutot du sscanf)
                  • et si elles ne sont pas correctes, en tenir compte.

                  (*) la complication, c'est qu'en C, lire une ligne complete dont on ne connait pas a priori la longueur, c'est pas un truc de débutant de deuxième semaine. Ca serait dans un langage civilisé, on écrirait ligne = nextLine().

                  -
                  Edité par michelbillaud 14 septembre 2018 à 13:55:58

                  • Partager sur Facebook
                  • Partager sur Twitter
                    14 septembre 2018 à 13:54:45

                    D'accord merci donc il faudrait faire une sorte d'entonnoir qui ne garde que les chiffres en l'occurrence, et supprimer les lettres c'est bien ça ?
                    • Partager sur Facebook
                    • Partager sur Twitter
                      14 septembre 2018 à 13:57:10

                      un entonnoir et une passoire, ainsi qu'une écumoire, ça peut toujours servir.

                      • Partager sur Facebook
                      • Partager sur Twitter
                        14 septembre 2018 à 14:57:40

                        Très bien et bien je vais essayer de chercher sur le sujet comment trier les caractères récupés :)
                        • Partager sur Facebook
                        • Partager sur Twitter

                        Petit problème de débutant

                        × 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