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

Fermé
Utilisateur anonyme - 20 mars 2010 à 12:47
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 - 20 mars 2010 à 22:03
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 47 Date d'inscription vendredi 8 février 2008 Statut Membre Dernière intervention 27 novembre 2013 2
20 mars 2010 à 13:11
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
20 mars 2010 à 13:16
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
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 47 Date d'inscription vendredi 8 février 2008 Statut Membre Dernière intervention 27 novembre 2013 2
20 mars 2010 à 14:00
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 47 Date d'inscription vendredi 8 février 2008 Statut Membre Dernière intervention 27 novembre 2013 2
20 mars 2010 à 14:15
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
20 mars 2010 à 14:28
la 2è fois aussi ???
0
Knuckles42 Messages postés 47 Date d'inscription vendredi 8 février 2008 Statut Membre Dernière intervention 27 novembre 2013 2
20 mars 2010 à 14:36
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
20 mars 2010 à 14:42
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 47 Date d'inscription vendredi 8 février 2008 Statut Membre Dernière intervention 27 novembre 2013 2
20 mars 2010 à 15:22
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
20 mars 2010 à 20:03
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 26 Date d'inscription samedi 20 mars 2010 Statut Membre Dernière intervention 10 juin 2011 4
Modifié par bokhabrine le 20/03/2010 à 20:47
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 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 843
20 mars 2010 à 22:03
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