Partage
  • Partager sur Facebook
  • Partager sur Twitter

getchar && putchar + scanf

    15 janvier 2020 à 13:09:25

    Hello tout le monde :) 

    J'ai récemment essayé le programme suivant

    int main()
    {
        int a;
        char c;
        printf("Indiquez le prix hors taxe d'un produit : ");
        rewind(stdin);
        scanf("%d",&a);
        printf("Indiquez en minuscule la categorie du produit a pour 5.5 b pour 20: ");
        rewind(stdin);
        c = getchar();
        printf("Character entered: ");
        putchar(c);
    
        return 0;
    
    }

    Le problème c'est que le programme s'exécute sans jamais me demander d'entrer le caractère c (je l'ai pourtant demandé avec l'instruction getchar).

    lorsque j'utilise un scanf à la place tout se passe très bien de même si j'utilise le programme suivant

    #include <stdio.h>
    
    int main () {
       char c;
     
       printf("Enter character: ");
       c = getchar();
     
       printf("Character entered: ");
       putchar(c);
    
       return(0);
    }

    Alors tout se passe très bien aussi.

    Du coup pourquoi ça marche pas ? Vraiment là je sèche !Merci de m'avoir lue !


    -
    Edité par MargauxLLL 15 janvier 2020 à 13:10:57

    • Partager sur Facebook
    • Partager sur Twitter
      15 janvier 2020 à 15:02:11

      rewind(stdin) n'est pas une utilisation standard. Il peut y a voir de drôles de surprises.
      Où as-tu vu cette utilisation de cette fonction ?

      getchar() lit un caractère de l'entrée standard.
      Le soucis c'est qu'il y a un '\n' ou un "\r\n" après la lecture de ton prix (puisque tu est revenu à la ligne pour terminer la saisie)

      test que sans les rewind(stdin) et en marquant pour la première saisie "1000b" , tu auras 1000 pour le prix et 'b' comme catégorie.

      Un petit code pour vidéer stdin et de manière standard.
      Le lit les caractères tant que je n'ai pas lu '\n' ou bien que j'ai atteint la fin du flux.
      void purge_stdin()
      {
       int c;
       do
       {
        c=getchar();//je lis un caractère et getchar renvoie un int ( sinon je ne peux pas récupérer EOF pour EndOfFile )
       }
       while (c != '\n' && c != EOF);
      }



      • Partager sur Facebook
      • Partager sur Twitter
        15 janvier 2020 à 15:06:07

        Salut,
        Je ne sais pas pourquoi tu fais un rewind(stdin), on ne fait jamais cela.
        Le système se place peut-être devant un caractère "Enter" ...
        t
        • Partager sur Facebook
        • Partager sur Twitter

        Le Tout est souvent plus grand que la somme de ses parties.

          15 janvier 2020 à 15:32:51

          Merci à vous deux pour vos réponses !

          @neuneutrinos

          Si je comprends bien getchar prend un caractère inséré même si celui si ne vient pas de l'appel de getchar lui même (ça j'avoue que j'ai du mal à saisir) ? En fait c'est comme si il lisait la ligne sur ce fameux fichier stdin et en retirait la caractère ?

          D'ailleurs  ou je me trompe ou ton bout de code permet de lire une nouvelle ligne pas d’effacer l’ancienne ? Tu me fais prendre conscience que je comprends pas du tout ce fichier stdin..

          PS; j'ai vue rewind(stdin) dans un livre (Langage C Maîtriser la programmation procédurale). Après j'ai probablement pas compris ce que voulait me dire l'auteur.

          • Partager sur Facebook
          • Partager sur Twitter
            15 janvier 2020 à 16:12:37

            getchar lit un caractère dans stdin.

            pour donner un exemple.

            Bonjour        toi   8  9
            fscanf(%s%s%d%d,a,b,&c,&d);//le formatage ignore les caractères d'espacement
            //a="Bonjour"
            //b="toi"
            //c=8
            //d=9

            Maintenant getchar.
            1000 b
            scanf("%d%c",&a,&b);//ou bien scanf("%d",&a); b=getchar();
            //a = 1000
            //b = ' '
            %c (ou getchar) n'ignore pas les caractères d'espacement.

            astuce ?
            On peut purger stdin (enlever en lisant tous les caractères restant dans stdin)
            ou bien profiter de la lecture formattée.
            scanf("%d%1s",&a,&b);//%1s au lieu de %c
            
            Il faudra faire attention de lire dans une chaine avec une taille minimale de 2.

            int prix;
            char categ;
            
            char buffer[2];//pour profiter de la lecture formatée
            
            scanf("%d%1s",&prix,buffer);
            categ=buffer[0];





            -
            Edité par neuneutrinos 15 janvier 2020 à 16:14:22

            • Partager sur Facebook
            • Partager sur Twitter
              15 janvier 2020 à 17:36:18

              @neuneutrinos;
              Quand tu dis que le formatage ignore les espacements, il faut être prudent.
              si je fais scanf("%d %d", &i, &j); je dois mettre l'espace entre les nombres. Sinon, il attend le second nombre après le Enter.
              Si je fais scanf("%d%d", &i, &j); je dois encore mettre un espace entre les nombres.
              Si je mets des lettres à la place du premier nombre, il me donnera 0 et attendra encore pour le deuxième.
              • Partager sur Facebook
              • Partager sur Twitter

              Le Tout est souvent plus grand que la somme de ses parties.

                16 janvier 2020 à 9:58:08

                Je ne mettrai pas ça comme un problème d'espacement.

                123345
                combien de nombre ? 1 seul. si tu demandes 2 nombre , il en manquera fatalement 1.

                Si maintenant à la place d'un nombre décimal , il y a autre chose. (il y a ici une erreur)
                Bob
                scanf("%d",&val);//que va-t-il se passer ?
                scanf ignore les caractère d'espacement, mais une lettre, un chiffre, une ponctuation,etc... ne sont pas des caractères d'espacement et ne seront pas ignorés.
                De plus, scanf retourne le nombre de variable correctement lu. ( et donc dans mon cas , il retournera 0 car rien n'aura été correctement lu) 

                Dans ce cas , val ne sera pas modifié, et tout se passera comme si stdin n'avait pas été lu.


                Si maintenant j'écrits

                //contenu qui sera dans stdin
                123 345\n
                
                scanf("%d%d",&a,&b);//a=123 et b=345 aucun problème.

                -
                Edité par neuneutrinos 16 janvier 2020 à 9:58:45

                • Partager sur Facebook
                • Partager sur Twitter
                  16 janvier 2020 à 12:17:31

                  Reprenons calmement.

                  Quand on fait une lecture (scanf, getchar, ...) sur le terminal, l'utilisateur tape une LIGNE.

                  Cette ligne est gardée quelque part, dans une zone tampon, et "consommée" par les lectures qu'on fait. Quand on est arrivé au bout, l'utiisateur a l'occasion de taper une nouvelle ligne.

                  bref, quand on a fait un scanf("%d", &nombre), il reste dans le tampon le caractère de fin de ligne.

                  -
                  Edité par michelbillaud 16 janvier 2020 à 12:18:24

                  • Partager sur Facebook
                  • Partager sur Twitter

                  getchar && putchar + scanf

                  × 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