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 :

probleme de scanf


Sujet :

C

  1. #1
    Membre éclairé Avatar de ralf91
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    419
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 419
    Par défaut probleme de scanf
    bonjour,
    j'ai un grand probleme avec le scanf() !!!
    j'ai un scanf() qui demande un entier c'est a dire avec x un entier, mais si l'utilisateur fait saisir un char au lieu d'un int le programme bloque ! c'est claire, mais moi ce que je veux c'est de faire une petite boucle qui demande a l'utilisateur d entrer une nouvelle valeur tant le scanf n a pas trouver de int (tant que l'utilisateur n'a pas entre un int), pour cela ils m'ont propose un programme que je n'ai pas vraiment comment il fonctionne voila son code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include<stdio.h>
    #include<stdlib.h>
     
     
    int main(void)
    {
    char buffer[256]= "";
    int valeur= 0;
     
    fgets(buffer, 255,stdin);
    valeur = atoi(buffer);
     
    return 0;
    }

  2. #2
    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
    Salut,

    Qu'est ce que tu ne comprends pas exactement? fgets() est une bonne solution pour faire ce que tu veux faire. Couplée à strtol() ou sscanf() (atoi est obsolète), cette fonction te permettra de saisir un entier de manière sécurisée et propre. Cette question revient souvent sur le forum, et tu trouveras dans les archives de nombreuses lignes de code commentées avec des explications exhaustives.

    Voici un exemple de saisie à d'entier à base de fgets(). Pose des questions si tu ne comprends pas:
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    /* Nettoyage après utilisation de fgets() */
    void fclean(char *s_tampon, FILE *fp)
    {
        /* On recherche le caractère de fin de ligne dans le tampon */
        char *pc = strchr(s_tampon, '\n');
     
        if (pc != NULL) /* Si le caractère de fin de ligne a été trouvé... */
        {
            /* ... on l'efface */
            *pc = 0;
        }
        else /* Sinon */
        {
            /* On vide le tampon du flux entrant (fichier ou entrée standard)*/
            int c;
            while ((c = fgetc(fp)) != '\n' && c != EOF)
            {
                continue;
            }
        }
    }
     
     
    int main(void)
    {
        char s_tampon[15] = {0};
        char *pend = NULL;
        int nombre = 0;
     
        do
        {
            printf("Veuillez entrer un nombre: ");
            fflush(stdout);
     
            if (fgets(s_tampon, sizeof s_tampon, stdin) != NULL)
            {
                fclean(s_tampon, stdin);
                nombre = strtol(s_tampon, &pend, 0);
            }
        } while (*s_tampon == 0 || *pend != 0);
     
        printf("Le nombre que vous avez entré est %d\n", nombre);
     
        return EXIT_SUCCESS;
    }
    Cela peut te sembler compliqué, mais une fois que ta fonction fclean() est écrite, tu la mets bien au chaud dans une bibliothèque de fonctions, et tu fais des saisies sécurisées en quelques lignes de code.

    Pour apprendre à construire tes propres fonctions de saisie robuste et sécurisées, je te conseille la lecture suivante: http://emmanuel-delahaye.developpez.com/inputs.htm N'oublie pas également de fouiller dans les archives de ce forum pour trouver des exemples de techniques permettant de réaliser des fonctions d'entrées/sorties sûres.

    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++

    +

  3. #3
    Membre éclairé Avatar de ralf91
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    419
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 419
    Par défaut
    salut,
    le programme que je vous ai envoye ce n est pas ce que je veux vraiment, car si vous lui ajoutez une boucle pour verifier par exemple :
    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
    #include<stdio.h>
    #include<stdlib.h>
     
     
    int main(void)
    {
    char buffer[256]= "";
    int valeur= 0;
     
    do
    {
      fgets(buffer, 255,stdin);
      valeur = atoi(buffer);
      if(valeur==1) 
        printf("erreur");
    }
    while(valeur==1);
     
    return 0;
    }
    c'est vrai qu'il affiche des erreur lorsque on lui donne un char mais je ne peux pas recuperer le int ?
    pour verfier j'ai ajoute un printf j'ai trouve que fgets(buffer, 255,stdin); donne un code, donc je ne peux pas recuperer la variable buffer pour l'utiliser dans la suite, pour verifier voila ce que j'ai fait :
    il m'affichera une valeur 2233..
    et ce que je veux c'est recuperer un entier et pas son code
    merci pour votre aide
    a+

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    On utilise printf("%s", buffer) pour afficher la chaîne, ou printf("%d", valeur) pour afficher l'entier converti...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre éclairé Avatar de ralf91
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    419
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 419
    Par défaut
    salut,
    ah oui c'est vrai pour afficher une chaine il faut utiliser %s, mais valeur recoit soit un 1 si l'utilisateur fait entrer un char et 0 si autre non ?
    donc si je mets j'aurai un 0 a cause de la boucle

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ben non, atoi() retourne 42 si la chaîne passée en paramètre est "42"...
    Et zéro en cas d'échec de la conversion.

    strtol() fait la même chose, mais avec une meilleure gestion des erreurs.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  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 ralf91
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    char buffer[256]= "";
    /* ...*/
    do
    {
      fgets(buffer, 255,stdin);
      valeur = atoi(buffer);
      if(valeur==1) 
        printf("erreur");
    }
    /* ...*/
    Pourquoi passes-tu 255 et non 256 ou sizeof buffer à fgets()? fgets() est sure de ce côté là. N'oublie pas qu'après chaque usage de fgets(), il est conseillé de vérifier la présence du caractère de fin de ligne dans le tampon (et éventuellement l'effacer), et en cas d'absence de ce caractère, de vider les caractères encore présents dans le tampon du flux entrant. Pour cela, tu peux utiliser la fonction fclean() donnée plus haut.

    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
    Membre éclairé Avatar de ralf91
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    419
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 419
    Par défaut
    salut mujigka,
    255 lui manque un 1 c'est ce que tu veux dire ben 1 c'est pour '\0' craractere de fin de chaine
    voila a+

  9. #9
    Membre éclairé Avatar de ralf91
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    419
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 419
    Par défaut
    salut,
    256 c'est le monbre de caractere que chaine peut contenir, mais c'est la taille en memoire c'est 4octets je pense

  10. #10
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Citation Envoyé par ralf91
    salut,
    256 c'est le monbre de caractere que chaine peut contenir, mais c'est la taille en memoire c'est 4octets je pense
    Pas si le tableau est alloué statiquement et dans le contexte courant de la compilation -> dans la même fonction par exemple.

    Jc

  11. #11
    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 ralf91
    salut mujigka,
    255 lui manque un 1 c'est ce que tu veux dire ben 1 c'est pour '\0' craractere de fin de chaine
    voila a+
    fgets() ajoute de toute manière un caractère nul à la fin du tampon, tu n'as donc pas besoin de le prévoir. Dans le contexte de ton code, sizeof buffer vaut 256, car ton tableau est alloué statiquement.

    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++

    +

Discussions similaires

  1. Probleme avec scanf et printf imbriqués
    Par nozgarde dans le forum C
    Réponses: 8
    Dernier message: 11/04/2008, 11h24
  2. Probleme de scanf ou de malloc ?
    Par gotrunkssj dans le forum Bibliothèque standard
    Réponses: 7
    Dernier message: 24/01/2008, 21h40
  3. problem avec scanf
    Par yous18 dans le forum Débuter
    Réponses: 5
    Dernier message: 14/09/2007, 03h24
  4. Probleme avec scanf
    Par LinuxUser dans le forum C
    Réponses: 3
    Dernier message: 17/05/2007, 14h18
  5. Probleme Avec Scanf Et Gets !
    Par A_B dans le forum C
    Réponses: 11
    Dernier message: 09/03/2007, 21h20

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