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 :

passer FILE* en argument d une fonction


Sujet :

C

  1. #1
    Candidat au Club
    Inscrit en
    Avril 2003
    Messages
    1
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 1
    Points : 2
    Points
    2
    Par défaut passer FILE* en argument d une fonction
    Salut,
    je voudrais passer un argument de type FILE* dans differentes fonctions de prototype
    void ouvrir_fic(FILE*)
    void ecrire_fic(FILE*)
    void fermer_fic(FILE*)

    a partir du main().
    apparemment, un code du type :

    void ouvrir_fic(FILE* f){
    f=fopen("baba","wt");
    ......etc .....



    int main(void){
    FILE* fic;
    ouvrir_fic(fic);
    ecrire_fic(fic);
    fermer_fic(fic);
    return 0;
    }

    ne marche pas
    si vous pouvez m'expiquer comment passer ce FILE* en argument...
    merci

    PS: solutions avec variable globale s'abstenir

  2. #2
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    C'est un probleme de passage par valeur :

    lorsque tu passe FILE* f en parametre de ouvrir_fic, tu passe le pointeur. Puis ensuite tu modifie ce pointeur (f=fopen(...)) mais lorsque tu reviens dans la fonction appelante f vaut ce qu'il vallait avant l'appel et non la nouvelle valeur. Pour corriger ce probleme, soit tu fais retourner le pointeur a la fonction ouvrir_fic plutot que de le passer en parametre, soit tu passes en parametre un pointeur sur le pointeur et le code devient alors :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void ouvrir_fic(FILE** f){ 
    *f=fopen("baba","wt"); 
    ......etc ..... 
     
     
     
    int main(void){ 
    FILE* fic; 
    ouvrir_fic(&fic); 
    ecrire_fic(fic); 
    fermer_fic(fic); 
    return 0; 
    }

    Autre remarque en passant, si tu pouvais utiliser les balises codes a l'avenir s'il te plait.

  3. #3
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    En fait le seul problème vient de fopen() qui modifie le pointeur f.

    Du coup pour la fonction d'ouverture tu dois passer l'adresse de f :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void ouvrir_fic(FILE** f){
    *f=fopen("baba","wt");
    ......etc ..... 
    }
    Le reste devrait marcher normalement...

    a++

  4. #4
    Membre habitué
    Avatar de barthelv
    Inscrit en
    Mars 2003
    Messages
    267
    Détails du profil
    Informations forums :
    Inscription : Mars 2003
    Messages : 267
    Points : 126
    Points
    126
    Par défaut attention aux pointeurs
    Ce qu'il faut savoir, c'est que lorsque tu passes en paramètre une valeur que tu veux modifier et récupérer, tu dois en fait passer un pointeur sur celle-ci.

    Ainsi,

    si tu veux modifier un char, tu dois passer un char *
    si tu veux modifier un char *, tu dois passer un char **

    et de même pour le type FILE.

  5. #5
    Membre éclairé
    Avatar de D[r]eadLock
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    504
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 504
    Points : 750
    Points
    750
    Par défaut
    Autre solution: si tu n'as qu'un seul parametre a changer, alors tu peux le passer au return :
    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
    FILE *ouvrir_fic(void);
    void ecrire_fic(FILE*) 
    void fermer_fic(FILE*) 
     
    FILE *ouvrir_fic(void){ 
        FILE *f=fopen("baba","wt"); 
        ......etc ..... 
        return f;
    }
     
     
    int main(void){ 
    FILE* fic; 
    fic=ouvrir_fic(); 
    ecrire_fic(fic); 
    fermer_fic(fic); 
    return 0; 
    }

  6. #6
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut
    Citation Envoyé par gl
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void ouvrir_fic(FILE** f){ 
    *f=fopen("baba","wt"); 
    ......etc ..... 
     
     
     
    int main(void){ 
    FILE* fic; 
    ouvrir_fic(&fic); 
    ecrire_fic(fic); 
    fermer_fic(fic); 
    return 0; 
    }
    Je vois pk on doit passer un ptr de ptr mais je comprend pas cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ouvrir_fic(&fic) ;
    Pourquoi on passe l'adresse du pointeur FILE* fic alors que dans la fonction, on doit passer un ptr de ptr ...
    Moi j'aurais par exemple penser a faire ca :
    mais je sais que c'est faux !

    Quand on veut passer un pointeur, on fait ca par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int* ptr ;
    int function(ptr) {
    ...}
    Dans le pssage, on ne fait pas apparaitre l'astérixe (*) car c'est l'adresse et non le contenu que l'on passe .
    Alors je comprend pas pk dans l'exemple donné, tu passe l'adresse du pointeur (et non l'adresse de la variable pointée) en param, puiske dab, comme en haut, on enleve un astérix, la ne doit-on pas enlever un astérix et il en reste un ??

    Merci car la j'aimerais comprendre

    Nas'

  7. #7
    Membre éclairé
    Avatar de D[r]eadLock
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    504
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 504
    Points : 750
    Points
    750
    Par défaut
    Citation Envoyé par NASKY
    Je vois pk on doit passer un ptr de ptr mais je comprend pas cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ouvrir_fic(&fic) ;
    Pourquoi on passe l'adresse du pointeur FILE* fic alors que dans la fonction, on doit passer un ptr de ptr ...
    Moi j'aurais par exemple penser a faire ca :
    mais je sais que c'est faux !
    Tu dois pas piger un truc .
    Quand tu ecris ca : int *ptr, tu dis : je definis une variable ptr qui pointe sur un int. C'est donc une adresse (qui tiens pour simplifier sur 32 bits).
    qui vaut par exemple (0x00000123).
    Maintenant, si tu veux l'adresse de cette variable c'est &ptr. Par exemple dans ton code, cette variable est bien a un endroit en memoire. Donc &ptr est l'adresse de cette variable (par exemple 0x23FF230F). Enfin, si tu accede a *ptr, tu prend la valeur pointee par ptr, c'est a dire le nombre situee a l'adresse 0x000000123 en memoire).

    Tu peux aussi lire le type autrement : int *ptr, veut dire que ptr est de type int *, mais aussi que *ptr est de type int ! C'est-a-dire que la variable pointee par ptr est de type int !

    Il ne faut pas confondre definition de fonction/variable et utilisation. En effet, si tu definit un pointeur d'entier int *ptr, et que tu as une fonction qui prend comme parametre un pointeur, le prototype de cette fonction est void fonc(int *ptr){... . En revenche, l'appel se fait avec une variable de type pointeur d'entier donc ptr, ou, si tu n'as qu'une variable de type entier, tu prend son adresse (c'est-a-dire, si c'est int i; tu appelle avec fonc(&i)).

    Exemple complet :
    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
     
    #include <stdio.h>
    void fonc(int *ptr){
        /* on affiche l'adresse et la valeur */
        printf("La valeur situee a l'adresse %p vaut %d\n",ptr,*ptr);
        return;
    }
     
    int main(void){
        int i,j;
        int *ptr;
        i=0;
        j=15;
        ptr=& /* ptr pointe sur j <=> ptr prend l'adresse de j */
        fonc(&i);
        fonc(ptr);
        fonc(&j);
        *ptr=124; /* on modifie la valeur pointee par ptr (c'est a dire j) */
        fonc(ptr);
        fonc(&j);
        return 0;
    }

  8. #8
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut
    Oui ca je l'avais compris et je l'ai mis dans un de mes exemples.
    J'ai compris que *ptr contient la valeur alors que ptr contient l'adresse de l'objet pointé et que &ptr contient l'adresse du pointeur.

    Mais ma question était plus centrée sur les pointeurs de pointeurs et plus précisement sur l'exemple mis par Gl .

    Dès que j'ai posté mon message, j'ai en fait, je crois, compris pk il a passé l'adresse du pointeur.
    Ne serai-ce pas car :
    FILE ** fichier --> un pointeur qui pointe sur le pointeur de fichier.
    Donc si on décompose cela en 2 pointeurs on a :
    ptr2 pointe sur ptr1 donc ptr2 contient l'adresse de ptr1. Or ptr1 est un pointeur donc on doit passer à la fonction l'adresse du pointeur donc on passe &fichier et non *fichier ...

    Je pense que c'est ca , enfin j'espère !

    Merci Dread pour la réponse qd mm

    Nas'

  9. #9
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par NASKY
    Dès que j'ai posté mon message, j'ai en fait, je crois, compris pk il a passé l'adresse du pointeur.
    Ne serai-ce pas car :
    FILE ** fichier --> un pointeur qui pointe sur le pointeur de fichier.
    Donc si on décompose cela en 2 pointeurs on a :
    ptr2 pointe sur ptr1 donc ptr2 contient l'adresse de ptr1. Or ptr1 est un pointeur donc on doit passer à la fonction l'adresse du pointeur donc on passe &fichier et non *fichier ...
    C'est ca.

  10. #10
    Membre éprouvé
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Points : 1 166
    Points
    1 166
    Par défaut
    Citation Envoyé par gl
    C'est ca.
    Merci . Je pense que c'est avec l'expérience qu'on maitrise ca, car moi je dois parfois refelchir "est ce que c'est l'adresse , la valeur, ke dois-je passer...." enfin des tonnes de questions ...
    Thx again.

    Nas'

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 03/05/2007, 07h49
  2. Réponses: 1
    Dernier message: 02/05/2007, 15h08
  3. Réponses: 17
    Dernier message: 24/11/2006, 18h25
  4. Réponses: 9
    Dernier message: 19/10/2006, 10h02
  5. Réponses: 14
    Dernier message: 16/05/2006, 11h26

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