IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

boucle infinie lors d'une saisie de lettre avec %ld et scanf


Sujet :

C

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    174
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 174
    Points : 74
    Points
    74
    Par défaut boucle infinie lors d'une saisie de lettre avec %ld et scanf
    Bonjour,
    j'aimerai comprendre pourquoi quand on entre une lettre qui est récupérer par le scanf le programme me fais un boucle infinie en me répétant que le printf(sans le scanf).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <stdio.h>
     
    int main()
    {
            int var=0;
            while(var==0)
            {
                    printf("entrer un nombre :\n");
                    scanf("%ld",&var);
     
            }
            return 0;
    }
    Je sais bien que %ld désigne un entier mais si on met une lettre, le programme devrait contenir le code ASCII de cette lettre ou au pire s'arrêter par bug : pourquoi une boucle infini alors? et pourquoi uniquement le printf() est répété indéfiniment...?

    merci d'avance

  2. #2
    Invité(e)
    Invité(e)
    Par défaut
    Citation Envoyé par sebatlante Voir le message
    Je sais bien que %ld désigne un entier mais si on met une lettre, le programme devrait contenir le code ASCII de cette lettre ou au pire s'arrêter par bug : pourquoi une boucle infini alors ? et pourquoi uniquement le printf() est répété indéfiniment...?
    Non, scanf est assez intelligent : si tu lui donne des lettres là où il attend des chiffres, il va dire que la conversion a échoué... par contre, il ne vide pas le buffer d'entrée : il faut le faire à la main :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #include <stdio.h>
     
    void purge(void)
    {
        int c;
        while ((c = fgetc(stdin)) != '\n' && c != EOF) {
        }
    }
     
    int main(void)
    {
        int ok;
        int var = 0;
        while (var == 0) {
            printf("entrer un nombre :\n");
            ok = scanf("%d", &var);
     
            if (1 == ok) {
                printf("la conversion a reussi\n");
            } else {
                printf("la conversion a echoue\n");
                purge();
            }
        }
        return 0;
    }

  3. #3
    Membre habitué
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    142
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 142
    Points : 154
    Points
    154
    Par défaut
    Salut,

    Essaye de mettre un fflush(stdin) juste apres ton scanf pour vider le buffer.

  4. #4
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par FunK92 Voir le message
    Essaye de mettre un fflush(stdin) juste apres ton scanf pour vider le buffer.
    Un petit lien sur la FAQ qui pourrait t'être utile.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 54
    Points : 53
    Points
    53
    Par défaut
    Je ne comprend pas pourquoi tu demandes de rentrer un nombre alors que tu attends une lettre ???

    Si c'est seulement pour faire l'equivalent de "appuyez sur une touche pour continuer" il existe une commande en C directement.

    Si c'est pour l'eventualité ou l'utilisateur rentre une lettre à la place d'un entier, tu peux faire une boucle pour ne pas prendre en compte les lettres, mais seulement les chiffres.


    Pour le scanf, oui en cours j'utilisais fflush(stdin) avant chaque scanf pour vider le buffer avant.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    fflush(stdin);
    scanf(%d, &var);

  6. #6
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Punition : copier 100 fois "je n'utiliserai pas fflush() sur stdin"
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 54
    Points : 53
    Points
    53
    Par défaut
    Voila une autre solution au probleme alors :


    l'utilsation de tcflush peut résoudre ce problème.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tcflush(cin, TCIFLUSH); /*  efface les données reçues mais non lues. */
    ou encore

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ioctl(cin,TCFLSH, TCIFLUSH); // quelque chose dans ce genre
    j'ai bien fais mon travail monsieur



    ps : pour eviter le probleme de l'utilisation de fflush(stdin)

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    174
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 174
    Points : 74
    Points
    74
    Par défaut
    merci pour toutes vos réponse ça résous mon problème.

    shadowking91, en faite c'est bien un nombre que je veux entrer. la raison pour laquel je rentre une lettre c'est tous simplement pour voir comment va réagir mon programme : en faite je ne veux pas qu'il fasse quelque chose que je n'aurai pas prévu qui serai un faille potentiel.

    bref, merci beaucoup à tous

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 54
    Points : 53
    Points
    53
    Par défaut
    Pour ceci, tu peux faire une boucle, d'apres la table ascii, les caracteres 0 à 9 sont (en hexa) compris entre 30 et 39 de la table

    donc une petite boucle avec ton scanf dedans, faire tantque l'utilisateur ne rentre pas un caractere compris entre 30 et 39 (ce qui equivaut aux chiffres 0 à 9)


    ou bien faire tantque la variable < 30 OU variable > 39

    Voila j'espere que ça pourra t'aider

  10. #10
    Invité(e)
    Invité(e)
    Par défaut
    Citation Envoyé par shadowking91 Voir le message
    Pour ceci, tu peux faire une boucle, d'apres la table ascii, les caracteres 0 à 9 sont (en hexa) compris entre 30 et 39 de la table

    donc une petite boucle avec ton scanf dedans, faire tantque l'utilisateur ne rentre pas un caractere compris entre 30 et 39 (ce qui equivaut aux chiffres 0 à 9)


    ou bien faire tantque la variable < 30 OU variable > 39

    Voila j'espere que ça pourra t'aider
    Cette méthode est compliquée. Si on veut lire caractère par caractère, il faut mieux utiliser fgetc et isdigit.
    (Et si vraiment on veut utiliser le code des caractères, il faut mieux utiliser '0' et '9' que 0x30 et 0x39)

Discussions similaires

  1. Sortir d'une boucle infinie lors d'un «shutdown aimable»
    Par spoutniksurf dans le forum Adaptive Server Enterprise
    Réponses: 2
    Dernier message: 10/12/2010, 15h15
  2. Boucle infinie lors d'un parcours d'une liste
    Par cocosql dans le forum Prolog
    Réponses: 3
    Dernier message: 16/01/2009, 07h23
  3. Réponses: 26
    Dernier message: 20/06/2006, 14h56
  4. [VBA-E]Tests lors d'une saisie
    Par aokiseiichiro dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 23/03/2006, 17h11
  5. Réponses: 3
    Dernier message: 06/07/2004, 10h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo