Langage C fonction scanf avec do while

Bonjour, j'ai un problème avec ma fonction scanf lorsque que je l'utilise avec la fonction do while.

Je m'explique :

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{

char i
int j=0;

do
{
printf("choisissez une lettre");
scanf("%c",&i)
printf("%c",i);
j=j+1;
}
while(j<6);

system("PAUSE");
return 0;
}

Voila en gros dans cet exemple simple, je devrais pouvoir taper écrire 6 lettres.
Or la fonction scanf semble marcher une fois sur deux, merci de m'expliquer pourquoi et comment remédier à ce problème SVP !! :)

6 réponses

  1. getchar() après ton scanf!
    0
    1. #include <stdio.h>
      #include <stdlib.h>

      void main(void)
      {
      char i;
      int j=0;
      while(j < 6)
      {
      printf("choisissez une lettre: ");
      scanf("%c",&i);
      fflush(stdin);
      printf("%c\n",i);
      j=j+1;
      }
      system("PAUSE");
      }

      résolu
      0
      1. Contributeur
        main() renvoie un int...
        fflush(stdin) n'est pas portable.
        Bref, la bonne version a été donnée il y a deux ans...
        0
    2. Déjà, il manque 2 ';' ...

      Ensuite, il faut comprendre que tu entres 2 caractères (ex : "a\n") et que tu n'en lis qu'un avec scanf() et "%c". Évidemment, chaque saisie fait 2 tours ...

      Pour remédier à ça, il faut lire le flux tant que le caractère lu n'est pas '\n'.

      C is a sharp tool

      #include <stdio.h> 
      #include <stdlib.h> 
      
      int main (void) 
      { 
         char i;                      /* -ed- manquait un ';' */ 
         int j = 0; 
      
         do 
         { 
            printf ("choisissez une lettre : "); 
            scanf ("%c", &i);         /* -ed- manquait un ';' */ 
      
            /* -ed- lire ce qui n'a pas été lu ... */ 
            if (i != '\n') 
            { 
               int c; 
               while ((c = getchar ()) != '\n' && c != EOF) 
               { 
      
               } 
            } 
            printf ("'%c'\n", i); 
            j = j + 1; 
         } 
         while (j < 6); 
      
         system ("PAUSE"); 
         return 0; 
      } 
      
      0
      1. voici une autre version plus lisible :

        #include <stdio.h>
        #include <stdlib.h>

        int main (void)
        {
        char i; /* -ed- manquait un ';' */
        int j = 0;

        do
        {
        printf ("choisissez une nombre : ");
        scanf ("%d",&i); /* -ed- manquait un ';' */

        /* -ed- lire ce qui n'a pas été lu ... */
        if (i != '\n')
        {
        int c;
        while ((c = getchar ()) != '\n' && c != EOF )
        {

        }
        }
        printf ("\n%d",i);

        j = j + 1;
        if (j==3)
        {
        printf( "\nil vous reste aucun choix\n\n");
        break;
        }

        printf(" \n\nil vous reste encore %d choix \n\n",3-j);

        }
        while (j < 4);

        system ("PAUSE");
        return 0;
        }
        0
      2. Contributeur
        Tu remontes un topic de 2 ans...
        Je ne trouve pas ton programme plus clair (peut-être est-ce l'effet de la non-indentation).
        En plus, mettre un scanf("%d", ...) et tester après si c'est différent de '\n', c'est incompatible...
        Et enfin c'est hors sujet (cf. énoncé : lire des caractères)
        0
    3. Contributeur
      Bonjour,

      Lorsque tu tapes une lettre lors de ton scanf("%c",&i), elle n'est envoyée que lorsque tu appuies sur la touche entrée. Or la touche entrée correspond au caractère '\r' transformée en '\n' à la volée. Conséquence, tu n'envoies pas un caractère dans le buffer mais deux caractères (la touche pressée + '\n').
      Ainsi lors de la première itération, ta variable "i" vaudra la touche voulue, et lors de la deuxième itération (sans même intervention de l'utilisateur puisqu'elle est déjà dans le buffer), "i" vaudra '\n'. Et à l'itération suivante, scanf redemandera à l'utilisateur de retaper un caractère (puisque le buffer est désormais vide).

      D'où l'impression que ça ne marche qu'une fois sur deux.

      Solution : vider le buffer à chaque itération. Par exemple, juste après le scanf, tu peux mettre ::
      while (getchar()!='\n');


      Note : je te conseille d'utiliser i=getchar(); plutôt que scanf("%c",&i);

      Cdlt,
      1
      1. pour vider le buffer tu met simple un fflush(stdin) après le scanf
        0