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 :

Utilisation de fgets


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut Utilisation de fgets
    Bonjour, je voudrai savoir comment utiliser une chaîne renvoyée par fgets pour créer un nom de fichier. Le nom du fichier effectivement créé est terminé par un '?', qui doit correspondre au '\0', le caractère de fin de chaîne. Pouvez vous me dire s'il existe un moyen connu de remédier à cela ? Merci beaucoup d'avance. Voilà mon programme :
    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
    62
    63
    64
    65
    #include <stdio.h>
    #include <stdlib.h>
     
    char * acqu(const char * mot)
       {
    /* 
    Allocation memoire pour
    la chaine acquise.
    */
       char * chaine = malloc(80*sizeof(char));
       if (chaine==NULL)
          printf("erreur malloc acqu\n");
       printf("Entrez %s\n", mot);
    /*
    acqisition de la chaine avec
    test sur la sortie de fgets
    */   
    if (fgets(chaine, 80, stdin)==NULL)
          printf("erreur fgets acqu");
       return chaine;
       }
     
    int main(void)
       {
    /*
    Allocation de memoire pour 
    les differentes chaines utilisees
    */
       const char * namefile = malloc(80*sizeof(char));
       const char * mail = malloc(80*sizeof(char));
       const char * pseudo = malloc(80*sizeof(char));
       const char * site = malloc(80*sizeof(char));
       const char * MdP = malloc(80*sizeof(char));
    /*
    initialisation des chaines constantes
    par la fonction char * acqu(const char *)
    */
       namefile = acqu("le nom de fichier");
       mail = acqu("l'adresse mail fournie");
       pseudo = acqu("le pseudo choisi");
       site = acqu("l'adresse du site");
       MdP = acqu("MdP");
    /*
    ouverture du fichier en ecriture
    */
       FILE * ptr_file;
       ptr_file = fopen(namefile,"w");
    /*
    ecriture dans le fichier de nom 
    contenu dans la chaine pointe par
    namefile de type const char *
    */   
     
       fprintf(ptr_file,"nom de fichier : %s\n",namefile);
       fprintf(ptr_file,"adresse fournie : %s\n",mail);
       fprintf(ptr_file,"pseudo : %s\n",pseudo);
       fprintf(ptr_file,"adresse internet : \n",site);
       fprintf(ptr_file,"MdP : %s\n",MdP);
    /*
    fermeture du fichier
    et fin du programme
    */
       fclose(ptr_file);
       return 0;
       }
    Je voudrai également savoir si l'utilisation de scanf("%s",char *) ne remplace pas avantageusement la fonction acqu. Merci beaucoup.
    __________________________________________________________________
    un bug dans l'édition de code par le forum :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    geneMdPalea.c: In function ‘main’:
    geneMdPalea.c:81: warning: passing argument 1 of ‘fprintf’ from incompatible pointer type
    geneMdPalea.c:82: warning: passing argument 1 of ‘fprintf’ from incompatible pointer type
    geneMdPalea.c:83: warning: passing argument 1 of ‘fprintf’ from incompatible pointer type
    geneMdPalea.c:84: warning: passing argument 1 of 'fprintf' from incompatible pointer type
    geneMdPalea.c:85: warning: passing argument 1 of 'fprintf' from incompatible pointer type
    • ‘-->le caractère incriminé
    • '-->celui là fonctionne

  2. #2
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Salut !


    Il faut toujours prendre soin de vérifier l'existence du caractère de saut de ligne, il faut le virer et le remplacer par un caractère nul:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char * p = strchr (chaine, '\n');
     
    if (p != NULL)
    {
       *p = 0;
    }
    A mons avis ca ne peut venir que de là ton problème
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  3. #3
    Membre éclairé
    Avatar de odsen.s
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    Par défaut
    Salut,

    J'ai plusieurs remarques sur ton code :
    • Pourquoi utiliser malloc pour une taille qui est fixe ? (Tu pourrais tout simplement créer des tableaux de caractères). De plus, sizeof(char) vaut 1 par définition
    • Tu ne testes pas l'ouverture de ton fichier

    Je voudrai également savoir si l'utilisation de scanf("%s",char *) ne remplace pas avantageusement la fonction acqu.
    scanf(), c'est le démon. Il faut être un expert pour l'utiliser correctement. Essaie plutôt de te construire des entrées sûres :
    http://emmanuel-delahaye.developpez.com/inputs.htm
    http://benoit.aun.free.fr/article_c_entrees_fiables.php

    Le nom du fichier effectivement créé est terminé par un '?', qui doit correspondre au '\0', le caractère de fin de chaîne.
    J'ai du mal a comprendre le problème. Peux-tu donner plus de détails ?
    EDIT : apparament Franck.H a répondu au problème

  4. #4
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut
    Citation Envoyé par odsen.s
    [LIST][*]Pourquoi utiliser malloc pour une taille qui est fixe ? (Tu pourrais tout simplement créer des tableaux de caractères). De plus, sizeof(char) vaut 1 par définition
    En fait j'ai gardé un mauvais souvenir du jour où j'ai voulu allouer une taille de tableau dynamiquement et que je n'ai pas pu le faire car les déclaration du genre " int tableau[taille] "où taille est une variable de typ int ne sont pas acceptées. C'est pour ça que je fais des malloc().

    Merci pour la remarque sur scanf(), j'avais bien vu des remarques sur les problèmes dans la saisie de nombres de type float par exemple, mais je n'en étais pas certain, j'avais vu aussi des exemples de saisie de chaîne caractère par caractère pour remplacer le scanf. Je demandais pour être sûr de ce qu'il ne faut pas faire sans réfléchir avant.

    Le scanf est vraiment la solution qui est enseignée dans les IUT par exemple, et séduisante puisqu'elle permet d'adapter le format de la saisie directement sans difficulté et d'adresser la variable correspondante, pratique par donc pour les float.

    Merci beaucoup en tout cas.

  5. #5
    Membre émérite Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Par défaut
    Beaucoup d'erreurs pour faire si peu de chose....

    Quel est l'interêt de l'allocation dynamique puisque aussitôt après tu modifies le pointeur ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
       const char * namefile = malloc(80*sizeof(char));
       const char * mail = malloc(80*sizeof(char));
       const char * pseudo = malloc(80*sizeof(char));
       const char * site = malloc(80*sizeof(char));
       const char * MdP = malloc(80*sizeof(char));
     
       namefile = acqu("le nom de fichier");
       mail = acqu("l'adresse mail fournie");
       pseudo = acqu("le pseudo choisi");
       site = acqu("l'adresse du site");
       MdP = acqu("MdP");
    Tu ne tests pas le retour de fopen. Imagines que la création du fichier soit impossible...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
       FILE * ptr_file;
       ptr_file = fopen(namefile,"w");
    Tu as oublié de libérer la mémoire précedemment allouée avant de quitter ton programme. De toute façon tu ne pourras pas le faire car tu as écrasé tes pointeurs.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
       fclose(ptr_file);
       return 0;
    Ci-dessous ton code légèrement modifié :
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define MAX_SIZE 80
     
    void acqu(char *chaine, size_t taille)
    {
        char *s = NULL;
     
        if (fgets(chaine, taille, stdin)!= NULL)
        {
            if ( (s = strchr (chaine, '\n')) != NULL )
            {
                *s = 0;
            }
        }
        else
        {
            puts("Erreur fgets !!!");
        }
    }
     
    int main(void)
    {
        char namefile[MAX_SIZE];
        char mail[MAX_SIZE];
        char pseudo[MAX_SIZE];
        char site[MAX_SIZE];
        char MdP[MAX_SIZE];
        FILE *ptr_file;
     
        printf("le nom de fichier : ");
        acqu(namefile, MAX_SIZE);
        printf("l'adresse mail fournie : ");
        acqu(mail, MAX_SIZE);
        printf("le pseudo choisi : ");
        acqu(pseudo, MAX_SIZE);
        printf("l'adresse du site : ");
        acqu(site, MAX_SIZE);
        printf("MdP : ");
        acqu(MdP, MAX_SIZE);
     
        if ((ptr_file = fopen(namefile,"w")) == NULL)
        {
            fprintf(stderr,"Impossible d'ouvrir le fichier en ecriture\n");
            exit(EXIT_FAILURE);
        }
     
        fprintf(ptr_file,"nom de fichier : %s\n",namefile);
        fprintf(ptr_file,"adresse fournie : %s\n",mail);
        fprintf(ptr_file,"pseudo : %s\n",pseudo);
        fprintf(ptr_file,"adresse internet : %s\n",site);
        fprintf(ptr_file,"MdP : %s\n",MdP);
        fclose(ptr_file);
     
        return EXIT_SUCCESS;
    }

  6. #6
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut
    Je voudrai savoir si fgets réalise l'allocation mémoire sur la chaîne passée en argument, où si l'appel à fgets nécessite de toutes les manières de préalablement déclarer la taille du tableau (de façon statique ou dynamique ). J'aimerai bien savoir aussi si l'allocation statique a une limite par rapport à l'allocation dynamique, c'est à dire si il est préférable d'utiliser l'allocation dynamique dans certains cas.

  7. #7
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Bien sûr que non elle n'alloue rien du tout, il faut que tu passes soit un tableau statique ou que tu alloues un espace que tu lui passes en argument !
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  8. #8
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut
    D'accord. Ce n'était pas implicite dans la page de manuel. Ça veut dire que l'allocation mémoire peut aussi bien se faire au sein de la fonction acqu, et peut être recopiée sur un simple pointeur de char sans avoir à allouer de la mémoire de façon dynamique ou statique pour chaque variable de type chaîne ?

  9. #9
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Tout ce qu'il faut c'est une adresse mémoire valide et de taille suffisante, après le reste tu fait comme tu veux
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

Discussions similaires

  1. Réponses: 3
    Dernier message: 18/05/2015, 23h19
  2. Est-ce une bonne utilisation de fgets ?
    Par clampin dans le forum C
    Réponses: 8
    Dernier message: 04/07/2007, 12h01
  3. [MySQL] Utilisation de str_replace dans une chaine fgets
    Par marciv dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 27/10/2006, 14h19
  4. utilisation de fgets: une question
    Par artatum dans le forum C
    Réponses: 5
    Dernier message: 27/09/2005, 17h27

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