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 :

Problème de scanf


Sujet :

C

  1. #1
    Membre régulier
    Inscrit en
    Août 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 7
    Par défaut Problème de scanf
    Salut tout le monde
    Ces derniers jours je travaille sur le programme C sous le shell bash
    Mon problème est le suivant :
    Lors de l’exécution d’un programme du genre :

    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
    #include <stdio.h>  
     
    int main()
    {
       char num;
     
       printf("Donner votre num: ");
       scanf("%c",&num);
       printf("Votre num est: %c ",num);
       printf("Donner votre code: ");
       scanf("%c",&num);
       printf("Votre code est: %c ",num);
     
       return 0; 
    }
    Lorsque je donne la première entrée et je click sur entrée le programme s’exécute entièrement et il ne me demande plus de saisir l’autre valeur
    Il affiche une sortie du genre :
    (la je donne la valeur f par exemple)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Votre num est: f Donner votre code: Votre code est:

  2. #2
    LLB
    LLB est déconnecté
    Membre émérite
    Inscrit en
    Mars 2002
    Messages
    968
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 968
    Par défaut
    Je te conseille d'utiliser un int et le format %d. Après test, chez moi, ça marche.

  3. #3
    Membre confirmé Avatar de Laughing Man
    Profil pro
    Inscrit en
    Août 2007
    Messages
    148
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Août 2007
    Messages : 148
    Par défaut
    je pense que ton problème vient du tampon
    avant chaque scanf essaie de mettre un fflush(stdin) pour voir.

  4. #4
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par nick_08 Voir le message
    Ces derniers jours je travaille sur le programme C sous le shell bash
    Mon problème est le suivant :
    Lors de l’exécution d’un programme du genre :
    <...>
    Lorsque je donne la première entrée et je click sur entrée le programme s’exécute entièrement et il ne me demande plus de saisir l’autre valeur
    Il affiche une sortie du genre :
    (la je donne la valeur f par exemple)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Votre num est: f Donner votre code: Votre code est:
    Un cas typique de mauvais usage de scanf(). Il y a 2 solutions :


    Une solution avec scanf()
    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
    27
    28
    29
    30
    31
     
    #include <stdio.h>
     
    int main (void)
    {
       char num;
     
       printf ("Donner votre num: ");
       scanf ("%c", &num);
       if (num != '\n')
       {
          int c;
          while ((c = getchar()) != '\n')
          {
          }
       }
       printf ("Votre num est: %c\n", num);
     
       printf ("Donner votre code: ");
       scanf ("%c", &num);
       if (num != '\n')
       {
          int c;
          while ((c = getchar()) != '\n')
          {
          }
       }
       printf ("Votre code est: %c\n", num);
     
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Donner votre num: 1
    Votre num est: 1
    Donner votre code: a
    Votre code est: a
     
    Press ENTER to continue.
    Evidemment, vu la répétitivité du code, on crée une fonction de nettoyage : purge() :
    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
    27
    28
    29
    30
     
    #include <stdio.h>
     
    static void purge(int val)
    {
       if (val != '\n')
       {
          int c;
          while ((c = getchar()) != '\n')
          {
          }
       }
    }
     
    int main (void)
    {
       char num;
     
       printf ("Donner votre num: ");
       scanf ("%c", &num);
       purge(num);
       printf ("Votre num est: %c\n", num);
     
       printf ("Donner votre code: ");
       scanf ("%c", &num);
       purge(num);
       printf ("Votre code est: %c\n", num);
     
       return 0;
    }

  5. #5
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Laughing Man Voir le message
    je pense que ton problème vient du tampon
    avant chaque scanf essaie de mettre un fflush(stdin) pour voir.
    Le diagnostic est correct, mais le remède est erroné. fflush() n'est défini que pour les flux sortants.

  6. #6
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par LLB Voir le message
    Je te conseille d'utiliser un int et le format %d. Après test, chez moi, ça marche.
    Sauf qu'en cas de saisie erronée, on retombe sur le même problème. De plus, le résultat est différent (il y a conversion texte -> valeur numérique).

  7. #7
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par Laughing Man Voir le message
    je pense que ton problème vient du tampon
    avant chaque scanf essaie de mettre un fflush(stdin) pour voir.
    Non! On le rappelle presque tous les jours sur ce forum: le comportement de fflush() n'est défini QUE pour un flux sortant. Cette fonction ne peut et ne doit par conséquent pas être utilisée pour purger le tampon du flux d'entrée standard (stdin).

    scanf() est une fonction très complexe et réservée aux spécialistes. Personnellement, je ne l'utilise jamais. La solution suivante à base de fgets() est parfaitement adaptée:
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    /* -TC- Cette fonction est a utiliser en complement de fgets() pour detecter
       eliminer le caractere de fin de ligne saisi pat cette dernière et purger
       le flux d'entree standard si necessaire */
    void fclean(char *tampoon, FILE *flux);
     
    int main(void)
    {
        /* -TC- Ce declare un tampon d'une longueur suffisante pour la saisie */
        char tampon[20] = "";
        char *pend = NULL;
        int num;
     
        do
        {
            printf("Donnez votre num: ");
            /* -TC- Cette fonction permet de purger le tampon du flux de sortie standard
               et de forcer l'affichage de "Donnez votre nom: " */
            fflush(stdout);
     
            fgets(tampon, sizeof tampon, stdin);
            fclean(tampon, stdin);
            num = strtol(tampon, &pend, 0);
        } while (*pend != 0);
     
        printf("Votre num est: %d\n", num);
     
        return 0;
    }
     
    void fclean(char *tampon, FILE *flux)
    {
        /* On cherche si le caractere '\n' est present */
        char *pc = strchr(tampon, '\n');
     
        if (pc != NULL)
        {
            /* -TC- Il est present: la saisie est donc complete */
     
            /* OPTIONNEL: On remplece de caractere de fin de ligne par un caractere
               nul */
            *pc = 0;
        }
        else
        { /* -TC- '\n' ne peut etre trouve' -> la saisie a ete tronquee et il reste
            des caracteres sur le flux d'entree standard */
     
            int c;
     
            /* -TC- On affiche un message d'avertissement*/
            fprintf(stderr, "ATTENTION: La saisie a été tronquée!\n");
     
            /* -TC- On vide le tampon du flux d'entree standard */
            while ((c = fgetc(flux)) != '\n' && c != EOF)
            {
            }
        }
    }
    N'hésite pas à poser des questions si tu ne comprends pas.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  8. #8
    LLB
    LLB est déconnecté
    Membre émérite
    Inscrit en
    Mars 2002
    Messages
    968
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 968
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Sauf qu'en cas de saisie erronée, on retombe sur le même problème. De plus, le résultat est différent (il y a conversion texte -> valeur numérique).
    Ah oui, en effet. À la base (avant modération), mon message indiquait surtout que la question était au mauvais endroit et qu'elle n'avait pas de rapport avec le Shell. Je n'aurais pas osé faire une réponse si simple sur le forum C.

  9. #9
    Membre confirmé Avatar de Laughing Man
    Profil pro
    Inscrit en
    Août 2007
    Messages
    148
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Août 2007
    Messages : 148
    Par défaut
    ué c'est vrai j'ai répondu trop vite. en fouillant dans mes sources j'ai retrouvé du fgetc partout
    du coup, la meilleure solution c'est de passer outre scanf pour entrer juste un caractère je pense
    désolé de cette réponse à deux ronds

  10. #10
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut
    Ou utilise fgets(maVar, sizeof maVar, stdin);

  11. #11
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Citation Envoyé par _SamSoft_ Voir le message
    Ou utilise fgets(maVar, sizeof maVar, stdin);
    Avec maVar de type char* ou char[].

  12. #12
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par _SamSoft_ Voir le message
    Ou utilise fgets(maVar, sizeof maVar, stdin);
    Si maVar est de type pointeur sur char, il y aura un problème, car dans ce cas, sizeof maVar vaudra sizeof (char *), ce qui ne correspond pas à la taille du tampon pointé par maVar.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void saisir_ligne(char *tampon, size_t longueur)
    {
        if (tampon != NULL)
        {
            /* ATTENTION: fgets(tampon, sizeof tampon, stdin) n'est PAS correct */
            fgets(tampon, longueur, stdin);
            fclean(tampon, stdin);
        }
    }
    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  13. #13
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut
    J'avais oublié les pointeurs

Discussions similaires

  1. Problème avec scanf("%s",str)
    Par mathieumadrid dans le forum C
    Réponses: 4
    Dernier message: 18/12/2006, 16h47
  2. problème avec scanf
    Par mimina dans le forum C
    Réponses: 27
    Dernier message: 13/11/2006, 19h30
  3. Problème de SCANF dans une boucle WHILE
    Par FidoDido® dans le forum C
    Réponses: 4
    Dernier message: 30/12/2005, 17h42
  4. problème avec scanf
    Par thierry_b dans le forum C
    Réponses: 10
    Dernier message: 21/12/2005, 20h10
  5. problème avec scanf
    Par troumad dans le forum C
    Réponses: 30
    Dernier message: 20/11/2005, 15h21

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