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 :

Scanf démythifiée...j'ai quand même une question ! [Non suivi]


Sujet :

C

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2004
    Messages : 5
    Points : 3
    Points
    3
    Par défaut Scanf démythifiée...j'ai quand même une question !
    Bonjour,

    J'ai lu la documentation à propos de la bonne utilisation de la fonction scanf. J'en suis content car elle pousse la réfléxion sur cette fonction un peu plus loin que le livre "Langage C" de C. Delannoy; du moins sur l'emploi de %[...]. C'est justement à ce propos que je viens demander votre aide.

    Si j'ai bien compris, pour vider le flux avec un la fonction scanf il suffit de taper ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    scanf("%*[^\n]");
    getchar();
    Alors, je me dis que ceci peut faire le même boulot:
    Hélàs, ça ne fonctionne pas très bien !

    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
     
    #include <stdio.h>
     
        main ()
    /*---------*/
    {
        int nbre;
     
        printf("Entrez un nombre de 3 chiffres: ");
        scanf("%3d[0-9]", &nbre);
        scanf("%*[^\n]%*c");
        //getchar();
        printf("Nombre lu: %d\n",nbre);
     
        printf("Entrez un caractere: ");
        getchar();
     
    } // fin main
    Si j'entre "123", alors il reste encore le '\n' (je crois ?) dans le buffer et le programme se termine sans que je puisse entrer un caractère.
    Si j'entre "1234", alors pas de problème. Le buffer semble être vidé après le second scanf. J'imagine qu'il restait '4' et '\n' donc forcément.

    Mais alors, que reste-t-il dans le buffer avec "123" ? Est-ce le '\0' ajouté par l'utilisation des "[" (si j'ai bien lu) ?

    Quelques intérrogations sur le scanf le mal aimé ;-)

    Merci d'avance et bonne soirée à tous
    ++

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut Re: Scanf démythifiée...j'ai quand même une question !
    Citation Envoyé par weiouch
    Je me contente de fgets(), maintenant, je sais pourquoi !
    Pas de Wi-Fi à la maison : CPL

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2004
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Bonjour,

    Est-ce parce que c'est correct et que ça devrait fonctionner ou parce que j'ai mal fait et plus compliqué que via fgets() ?

    ++

  4. #4
    Membre éprouvé
    Avatar de Pouic
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 669
    Points : 977
    Points
    977
    Par défaut
    Bonsoir,

    Le soucis avec ce genre de formule, c'est la chose suivante :
    On attend une suite de caractères différents de '\n' ([^\n]), et un caractère '\n' ( %c)

    Là, si le premier scanf réussi, et laisse dans stdin un '\n' (suite à ta saisie 123), eh bien scanf va échouer puisqu'on attend un caractère différent de '\n'.

    On arrive alors sur getchar, qui lui mange le '\n' restant, sans te faire attendre...
    C'est un comportement qui n'est pas forcément évident à voir...
    Je te conseille de t'amuser avec le formateur %n, de manière à voir où scanf échoue avec ton format. Tu verras que lorsqu'il reste uniquement un '\n' et que tu tentes un %*[^\n], ça échoue.
    Le %*c d'après n'est pas fait.

    C'est pour cela qu'il faut absolument passer par un getchar, et faire ça en deux étapes.

    J'espère avoir été un peu plus clair


    ps : tu vois que si la saisie est 1234, alors l'expression rationnelle à laquelle tu as pensé fonctionne : en effet, '4' est différent de '\n'

    pps :
    Citation Envoyé par Emmanuel Delahaye
    Je me contente de fgets(), maintenant, je sais pourquoi !
    Le vilain trolleur
    Software becomes slower faster than hardware becomes faster
    [size=1]
    http://xrenault.developpez.com

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2004
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Bonjour à tous,

    scanf va échouer puisqu'on attend un caractère différent de '\n'.
    Je suis d'accord qu'en tapant "123" il reste bien le '\n' dans stdin.
    Avec %*[^\n] on ignore tous les caractères différents de '\n'. Puisqu'il ne reste que '\n', on se positionne sur ce dernier. Logiquement, un %*c devrait donc lire le '\n'.

    D'ailleurs, ceci fonctionne bien:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    scanf("%*[^\n]"); scanf("%*c");
    Je ne comprends donc pas pourquoi scanf("%*[^\n]%*c"); ne fonctionne pas.

    Mon but n'est pas de troller sur scanf() VS fgets() mais simplement d'essayer de comprendre.

    Merci
    ++

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par weiouch
    Mon but n'est pas de troller sur scanf() VS fgets() mais simplement d'essayer de comprendre.
    Ce n'est pas à toi que la trollesque remarque s'adressait !

    "scanf() c'est trop fort pour moi !"
    Pas de Wi-Fi à la maison : CPL

Discussions similaires

  1. Une question qui est simple quand on connaît la réponse
    Par Neolander dans le forum Général Python
    Réponses: 5
    Dernier message: 05/12/2008, 07h25
  2. outre passer excel et quand même exécuter une macro excel : possible en VB ?
    Par chapeau_melon dans le forum VB 6 et antérieur
    Réponses: 17
    Dernier message: 08/11/2006, 20h59
  3. Une cellule sans contenu mais affichée quand même?
    Par petozak dans le forum Balisage (X)HTML et validation W3C
    Réponses: 30
    Dernier message: 30/08/2006, 18h19
  4. boucle simple dans une dataGrid avec quand même une erreur !
    Par fkr dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 07/11/2005, 15h04

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