Pbm en C... ce pgm entre 2fois dans un while

Utilisateur anonyme -  
fiddy Messages postés 11653 Statut Contributeur -
bonjour,
j'ai un petit programme a faire en C.
le main gère un menu qui permet de faire différentes chose.
voila une partie du code source:
char Menu(void)
{
char c=' ';
printf("== pour ajouter un élément tapez a ==\n");
printf("== pour supprimer un élément tapez d ==\n");
printf("== pour quitter tapez q ==\n");
printf("Choix? ");
scanf("%c",&c);

while(c != 'a' && c != 'A' && c != 'd' && c != 'D' && c != 'q' && c != 'Q')
{
printf("%c",c);
printf("\nveuillez entrer \"a\", \"d\", ou \"q\" : ");
scanf("%c",&c);
}
return c;
}

le problème c'est que si je tape un char autre que a,d, ou q il m'indique ceci:

veuillez entrer "a", "d", ou "q" :
veuillez entrer "a", "d", ou "q" : _

je ne comprend pas pourquoi il entre deux fois dans le while....

si quelqu'un sait m'aider......

Merci d'avance pour vos réponse ......

12 réponses

Knuckles42 Messages postés 48 Statut Membre 2
 
Bonjour,

Je vais peut-être te dire une bêtise, je crois savoir d'où viens le problème.

Quand tu entre ton caractère (autre que 'a', 'd' ou 'q') tu valides en appuyant sur 'Entrée' soit '\n', qui est un caractère qui est entrée dans le "buffer" (sauf erreur, mémoire tampon qui retient les entrées clavier).

La première fois que tu entre dans ta boucle, le caractère testé est celui que tu as tapé, mais la fonction scanf() dans le boucle va considérer le fameux '\n' de validation ...

Après chaque scanf(), je te propose d'insérer une fonction vider_buffer() dont le code est le suivant :

void vider_buffer()
{
int a = 0;
while (a != '\n' && a != EOF)
{
a = getchar();
}
}

Si tu n'es pas réfractaire au Site du zéro, tu trouveras plus d'infos ici : https://openclassrooms.com/fr/courses/19980-apprenez-a-programmer-en-c/16993-la-saisie-de-texte-securisee

J'espère ne pas t'avoir dit d'ânerie : je débute en C ...

Bon courage,
K42
0
Utilisateur anonyme
 
oui moi aussi j'ai songé a l'idée du \n qui posait problème, mais je ne savait pas comment le résoudre........ et débutant aussi en C je ne connaisait pas bien les buffer

Merci beaucoup a toi, je vais essayer sa...

0
Utilisateur anonyme
 
euhh encore un petit problème,
donc j'ai fait comme tu m'a dit, j'ai mit un ViderBuffer() après mes scanf:

char Menu(void)
{
char c=' ';
printf("== pour ajouter un élément tapez a ==\n");
printf("== pour supprimer un élément tapez d ==\n");
printf("== pour quitter tapez q ==\n");
printf("Choix? ");
scanf("%c",&c);
viderBuffer();
while(c != 'a' && c != 'A' && c != 'd' && c != 'D' && c != 'q' && c != 'Q')
{
printf("%c",c);
printf("\nveuillez entrer \"a\", \"d\", ou \"q\" : ");
scanf("%c",&c);
viderBuffer();
}
return c;
}

maintenant quand j'écris un mauvais caractère il me le dit bien

mais.
je lance je programme je tape 'a' il fonctionne bien
ensuite il me donne a nouveau le petit menu (c'est normal)
mais si je lui remet a il me dit veuillez entrer "a", "d", ou "q" :

si je réécrit a encore une fois 'a' il me l'accepte...

donc en gros il ne m'accepte le a (et les autres lettres) qu'une fois sur deux .....

a tu une idée ???????
0
Knuckles42 Messages postés 48 Statut Membre 2
 
Je t'avoue que je ne vois pas vraiment d'où vient le problème. Essaie d'ajouter :

printf("Le caractère qui va être testé est : -%c-\n", c);

juste avant la boucle while(), pour déterminer que vaut "c" avant la boucle, puisque, apparemment, ce n'est pas ce que tu as entré ...

J'ai volontairement ajouté des tirets entre le '%c' pour déterminer plus facilement le fameux caractère dans la console, surtout si c'est une espace ou un '\n'.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Knuckles42 Messages postés 48 Statut Membre 2
 
Maintenant que j'y pense, tu peut aussi vider le buffer avant les scanf(), et du coup, (selon moi !) ça devrait marcher ...

char Menu(void)
{
char c=' ';
printf("== pour ajouter un élément tapez a ==\n");
printf("== pour supprimer un élément tapez d ==\n");
printf("== pour quitter tapez q ==\n");
printf("Choix? ");
viderBuffer();
scanf("%c",&c);
viderBuffer();
while(c != 'a' && c != 'A' && c != 'd' && c != 'D' && c != 'q' && c != 'Q')
{
printf("%c",c);
printf("\nveuillez entrer \"a\", \"d\", ou \"q\" : ");
scanf("%c",&c);
viderBuffer();
}
return c;
} 
0
Utilisateur anonyme
 
la 2è fois aussi ???
0
Knuckles42 Messages postés 48 Statut Membre 2
 
Ce n'est pas utile, puisqu'il n'y pas d'autre entrée clavier entre le scanf() de la boucle et le viderBuffer() précédent (qu'elle que soit le nombre d'itération dans la boucle).

J'espère me faire comprendre !
0
Utilisateur anonyme
 
quand j'exécute la première fois le pgm
il aime pas vraiment .....

il me dit:
Choix : w (je tape le \n)
(je retape un \n)
(je reretape un \n)
et la il me dit : veuillez entrer "a", "d", ou "q"


mais après la première fois il fonctionne

=_=
0
Knuckles42 Messages postés 48 Statut Membre 2
 
Quand tu dis que ca marche pas la première fois, mais qu'ensuite ca fonctionne, tu parles du passage dans la boucle while() ou de la fonction Menu() ?
Qu'est ce que tu entends par "je tape le \n" ?
0
Utilisateur anonyme
 
ben "je tape le \n" je tape enter quoi ;)

et après avoir tapez 3fois sur la touche enter (la première fois que je lace le pgm)

il fonctionne parfaitement (avec les bonnes lettres)
et me dis bien les erreurs quand je met une mauvaise lettre
0
bokhabrine Messages postés 34 Statut Membre 4
 
bonsoir ; pour moi je propose gere le menu avec (select case)c'est la meileure solution si tu as bosion de code je te passerai
0
fiddy Messages postés 11653 Statut Contributeur 1 847
 
Bonsoir,
Effectivement le problème vient du fameux '\n'.
Par contre, il ne faut faire attention à ne pas lancer cette fonction avant le scanf auquel cas le programme tournerait en boucle.

Je te corrige le code et te le simplifie par la même occasion.

static void videBuffer() {
    int c;
    while((c=getchar())!='\n' && c!=EOF);
}

char Menu(void)
{
    char c=' ';
    printf("== pour ajouter un élément tapez a ==\n");
    printf("== pour supprimer un élément tapez d ==\n");
    printf("== pour quitter tapez q ==\n");

    printf("Choix? ");
    fflush(stdout);

    c=toupper(getchar());
    videBuffer();
    do {
        switch(c) {
            case 'A':
            case 'D':
            case 'Q':
                return c;
            default:
                printf("\nveuillez entrer \"a\", \"d\", ou \"q\" : ");
                c=toupper(getchar());
                videBuffer();
        }
    } while(c!=EOF);
    return -1;
}

N'oublie pas d'inclure ctype.h pour la fonction toupper qui convertit en majuscule. Ce qui t'évite de tester les caractères minuscules.

Cdlt,
0