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 avec la fonction gets


Sujet :

C

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 12
    Par défaut problème avec la fonction gets
    Bonjour, j'ai un problème avec la fonction gets.
    Apaprement, elle ne marche pas si avant je fais un scanf, ce qui me parait très bizarre :
    Si je fais ce code là, pas de problème :

    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>
    main()
    {
        int util1;
        char chaine[50];
        FILE *sortie;
        int a=1;
        if (a==1){          
            sortie=fopen("bonjour","w");
            fprintf(sortie,"BONJOUR\n");
            gets(chaine);
            fprintf(sortie," %s\n",chaine);
        }
    }
    Mais si je fais un scanf juste avant, ça ne marche pas : la chaine n'est pas demandée à l'utilisateur, alors que bonjour est écrit dans le fichier (ce qui prouve qu'on est bien rentré dans la boucle).

    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>
    main()
    {
        int util1;
        char chaine[50];
        FILE *sortie;
        int a;
        scanf("%d",&a);
        if (a==1){          
            sortie=fopen("bonjour","w");
            fprintf(sortie,"BONJOUR\n");
            gets(chaine);
            fprintf(sortie," %s\n",chaine);
        }
    }
    Est ce que vous pouvez m'aider? Merci!

  2. #2
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    168
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 168
    Par défaut
    Bonjour,

    pense à la balise

    sinon j'ai rien compris c'est quoi le problème , normalement tu as intialisé la variable a , où se situe le problème

    turbo_chess

  3. #3
    Membre émérite Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Par défaut
    Il reste le '\n' qui n'a pas été ôté par scanf() dans le buffer d'entrée. gets() le trouve et considère que la chaîne est déjà entrée et est vide.

  4. #4
    Membre émérite Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Par défaut
    Une solution consiste à écrire:

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 12
    Par défaut
    d'accord, merci beaucoup

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 12
    Par défaut
    Mais je ne comprends pas la solution que vous avez donné, car alors, on ne rentre plus dans la boucle.
    Je ne comprends vraiment pas comment je peux faire

  7. #7
    Membre émérite Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Par défaut
    Citation Envoyé par Laurran
    Mais je ne comprends pas la solution que vous avez donné, car alors, on ne rentre plus dans la boucle.
    Je ne comprends vraiment pas comment je peux faire
    De quelle boucle parlez-vous?

  8. #8
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    et aussi tu parles de fgets mais tu utilises gets.....

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    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 393
    Par défaut
    Je n'ai rien vu ici qui parle de fgets().

    Mais gets() est un bug et ne doit pas être utilisée du tout. Utiliser fgets() à la place (même si ça n'aurait pas résolu le problème du P.O.).

    PS: Quand sera-t-elle enfin officiellement deprecated ?
    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.

  10. #10
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Médinoc
    Je n'ai rien vu ici qui parle de fgets().

    Opps autant pour moi c'était tellement évident pour moi (fopen..)....

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 12
    Par défaut
    Mais je ne veux pas utiliser de fichier dans ce cas là, car je veux que ce soit l'utilisateur qui choisisse.
    Alors comment faire pour lire un entier à l'aide de scanf puis une chaine (avec espaces autorisés)???

    Merci

  12. #12
    Membre émérite Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Par défaut
    Citation Envoyé par Laurran
    Alors comment faire pour lire un entier à l'aide de scanf puis une chaine (avec espaces autorisés)???
    Comme je l'ai déjà écrit, voici une solution possible:
    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(void)
     {
     char s[50];
     int i;
     
     scanf("%d\n",&i);
     gets(s);
     printf("%d\t%s\n",i,s);
     return 0;
     }

  13. #13
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    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 393
    Par défaut
    Et Comme je l'ai déjà écrit, on n'utilise pas gets() :
    Code C : 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
    #include <stdio.h>
    #include <string.h>
     
    void purge(void)
    {
        int c;
        while( (c=getchar()) != '\n' && c != EOF)
        {
        }
    }
     
    void purgeString(char *s)
    {
        /* Soit il y a un \n dans la chaîne, soit il est toujours dans stdin */
        char * pLF = strchr(s, '\n');
        if(pLF != NULL)
        {
            /* Il est dans la chaîne, on le supprime. */
            *pLF = '\0';
        }
        else
        {
            /* Il est toujours dans stdin, on vide la ligne */
            purge();
        }
    }
     
     
    int main(void)
    {
        char s[50];
        int i;
     
        scanf("%d", &i);
        purge();
     
        fgets(s, 50, stdin);
        purgeString(s);
     
        printf("%d\t%s\n",i,s);
        return 0;
    }
    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.

  14. #14
    Membre émérite Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Par défaut
    Citation Envoyé par Médinoc
    Et Comme je l'ai déjà écrit, on n'utilise pas gets() :
    C'est bon; ici il s'agit d'un programme tout simple où l'utilisateur et le programmeur sont la même personne. Alors toutes ces précautions sont un peu superflues. Si l'utilisateur/programmeur est assez bête pour rentrer trop de caractères et que ça plante, tant pis pour lui. En outre, les dégâts causés par un éventuel plantage ne devraient pas être trop dramatiques.

  15. #15
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    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 393
    Par défaut
    C'est vrai qu'on ne code pas sur une DeathStation 9000, mais c'est un coup à prendre...

    Et ce n'est pas "toutes ces précautions", la seule précaution ici est d'utiliser fgets() à la place de gets().
    Le reste est nécessaire pour résoudre le problème originel : Que gets() ou fgets() marche même si on ne tape rien de valide pour scanf().
    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.

  16. #16
    Membre émérite Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Par défaut
    Citation Envoyé par Médinoc
    Et ce n'est pas "toutes ces précautions", la seule précaution ici est d'utiliser fgets() à la place de gets().
    Le reste est nécessaire pour résoudre le problème originel : Que gets() ou fgets() marche même si on ne tape rien de valide pour scanf().
    J'ai écrit "toutes" car les fonctions de purge ne sont pas nécessaires; ceci fonctionne:
    edit: Je suis d'accord que pour des programmes plus sérieux, il convient d'utiliser des routines d'entrée plus sécurisées. Mais pour de simples programmes console comme celui-ci, il ne me semble pas important de gérer ce genre de cas.

  17. #17
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    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 393
    Par défaut
    Perdu, si on entre une bêtise au lieu de "rien du tout", la seconde question n'est pas posée:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    a = -10;
    puts("Entrez a :");
    scanf("%d\n", &a);
    puts("Entrez buf :");
    gets(buf); /* Oui, gets(). Pour être sûr. */
    printf("%d\t%s\n",a, buf);
    Code sortie : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Entrez a :
    x
    Entrez buf :
    -10     x
    Ici, le printf() a eu lieu sans que je puisse taper quoi que ce fût dans "entrez buf" --> Problème originel non-résolu.
    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.

  18. #18
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    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 393
    Par défaut
    Et c'est encore plus marrant si on fait une boucle de scanf :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    a = 0;
    do
    {
    	puts("Entrez a entre 1 et 10:");
    	scanf("%d\n", &a);
    	printf("Vous avez saisi : %d\n.", a);
    }
    while( a < 1 || a > 10);
    Et tu tapes "x".
    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.

  19. #19
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 12
    Par défaut
    Merci beaucoup pour toutes vos réponses.
    Je ne suis pas sure d'avoir tout bien compris lorsqu'on n'utilise pas gets, mais avec gets ça marche.
    Merci beaucoup

  20. #20
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    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 393
    Par défaut
    Ça marche autant avec gets() qu'avec fgets(), sauf quand on tape plus que le buffer.

    Et aussi, fgets() ne retire pas tout seul le \n, c'est à ça que sert la fonction purgeString().
    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.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. problème avec la fonction get()
    Par Marciane dans le forum R
    Réponses: 3
    Dernier message: 17/05/2011, 13h35
  2. Problème avec la fonction findfirst ()
    Par Angelico dans le forum Windows
    Réponses: 3
    Dernier message: 05/08/2004, 20h40
  3. [Requete SQL en VBA] Problème avec la fonction FLOOR
    Par zubral dans le forum Langage SQL
    Réponses: 4
    Dernier message: 13/07/2004, 13h24
  4. Problème avec les fonctions
    Par jvachez dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 13/01/2004, 12h06
  5. [Postgresql]Problème avec les fonctions ...
    Par fet dans le forum Requêtes
    Réponses: 4
    Dernier message: 02/10/2003, 09h04

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