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 :

Tout le monde adore les pointeurs


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de crashtib
    Homme Profil pro
    Support technico-fonctionnel
    Inscrit en
    Avril 2009
    Messages
    221
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Support technico-fonctionnel
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 221
    Par défaut Tout le monde adore les pointeurs
    ...et moi aussi. A part quand ils marchent pas. je m'explique.

    Je fais appel à une sous-fonction nommée lireligne, qui lit les lignes d'un document qu'on lui passe en parametre (une ligne de début et une ligne de fin). Cette fonction renvoie un char * par ligne, donc un tableau de char *, donc un char **. Voici la fonction :
    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
    #include "biblio.h"
     
     
    //cette fonction lit les lignes d'un fichier dont le chemin est passe en argument.
    //elle renvoie un tableau de chaines de caracteres correspondant au contenu du document de la ligne debut jusqu'a la ligne fin
     
    char ** lireligne(char* nomfichier, int lignedebut, int lignefin)
    {
    	int i;
    	FILE * fichier;
    	char * donnees[1+lignefin-lignedebut];
    	char temp[512];
     
    	fichier = fopen (nomfichier, "r");
     
     
    	for (i = 1; i < lignedebut ; i++)
    	{
    		fgets(temp, sizeof(temp), fichier);
    	}
     
    	for (i = 0; i <= (lignefin-lignedebut) ; i++)
    	{
    		fgets(temp, sizeof(temp), fichier);
    		donnees[i] = (char *)malloc(sizeof(char)*strlen(temp));
    		strcpy(donnees[i], temp);
    	}
     
    	fclose(fichier);
    	return donnees;
     
    }
    Cette fonction marche, vous pouvez me croire. Le problème c'est quand j'essaie de la récupérer dans un programe père :
    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 "biblio.h"
     
    void* parser(void *p)
    {
    	int i;
    	printf("debut du parsing des fichiers GRE et FNR...\n");
     
    	char ** donnees = NULL;
     
    	donnees = lireligne("test.csv", 1, 6);
     
    	for(i = 0; i < sizeof(donnees) ; i++)
    	{
    		printf(donnees[i]);
    	}
    	return NULL;
     
     
     
    }
    parce que bizarrement la valeur de données ne voudra jamais changer de 4... alors que sizeof(donnees) dans lireligne vaut 64 (pour cet exemple).

    Pouvez-vous m'aider? Merci!

  2. #2
    Membre éprouvé
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2008
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2008
    Messages : 143
    Par défaut
    Tu ne teste pas si ton fichier à été correctement ouvert.

    Il se peut que tu ai un problème la dessus (bien que je suppose que ça planterait joliment...)

  3. #3
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    parce que bizarrement la valeur de données ne voudra jamais changer de 4... alors que sizeof(donnees) dans lireligne vaut 64
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	char ** donnees = NULL;
     ....
    	for(i = 0; i < sizeof(donnees);....
    Donnees est un pointeur, donc sizeof(donnees) donne la taille d'un pointeur ( probablement 4 bytes). C'est pas bizarre, (bizarre ,vous avez dit bizarre ?)

    Dans lireligne,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char * donnees[1+lignefin-lignedebut];
    donnees est un tableau de pointeurs (sur char). (tu compiles en C99 ?)
    Au moment de l'appel, on a (1+ 6-1)* sizeof(char*) soit 6*sizeof(char*) (probablement 24)

  4. #4
    Membre confirmé Avatar de crashtib
    Homme Profil pro
    Support technico-fonctionnel
    Inscrit en
    Avril 2009
    Messages
    221
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Support technico-fonctionnel
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 221
    Par défaut
    tout à fait. Ce qui est d'ailleurs marrant, c'est que aujourd'hui en relançant le bordel sizeof(donnees) dans lireligne vaut 24. Alors qu'hier ça valait 64. Allez savoir. Bref.

    Tu as raison de me faire penser à l'erreur à l'ouverture de fichier. C'est en effet un blidnage que je n'ai pas encore pris la peine de coder, mais crois-moi il n'y a pas d'erreur pour l'instant puisque lireligne me renvoie en effet le contenu de test.csv et parser.c me l'affiche. Le fichier est donc effectivement lu.

    Mais que de la ligne 1 à la ligne 4. Systématiquement.

    Par contre, autre bizarrerie, si je fais printf(donnees[5]); dans parser.c, cela va effectivement me donner la 6e ligne du fichier, comme escompté. J'en déduis que le pointeur a été correctement transmis, et le données sont transférées et utilisables. Reste que je n'arrive pas à savoir la taille du tableau, et je refuse de la fixer en dur dans le code.


    (tu compiles en C99 ?)
    C'est à dire? Quésaquo? Gné?

  5. #5
    Membre expérimenté Avatar de Ksempac
    Inscrit en
    Février 2007
    Messages
    165
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 165
    Par défaut
    Ca ne sert a rien te t'emballer. Tu n'as pas lu ce qu'a ecrit diogene, il t'a deja tout explique (il t'as meme "predit" la valeur 24 !), il n'y a rien de mysterieux.

    L'operateur sizeof() te donne la taille du type utilisé. En l'occurence un char*, c'est à dire un pointeur. Sur un systeme 32 bits, cela fait 4 bytes.
    Donc il est tout a fait normal que ta boucle for aille de 0 à 3, c'est à dire qu'il lit les lignes 1 à 4.

    Quant à C99, il s'agit d'une norme du langage C publiée en 1999 (d'ou le nom), plus récente que le C90. Certaines comportements/syntaxes different entre les 2 standards, mais les 2 sont frequemment utilisées, d'ou la question de diogene.

  6. #6
    Membre confirmé Avatar de Gui13
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2006
    Messages : 157
    Par défaut
    Tu alloues tes données sur la pile (d'ailleurs, je trouve bizarre que le compilo ne te mette pas d'erreur, car la taille de ton tableau "donnees" est dynamique), c'est normal que tu ne t'y retrouves pas.

    Il faut allouer sur le tas, en utilisant un malloc:

    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
    char ** lireligne(char* nomfichier, int lignedebut, int lignefin)
    {
    	int i;
    	FILE * fichier;
    	char ** donnees = malloc((1+lignefin-lignedebut),sizeof(char *));
    	char temp[512];
     
    	fichier = fopen (nomfichier, "r");
     
     
    	for (i = 1; i < lignedebut ; i++)
    	{
    		fgets(temp, sizeof(temp), fichier);
    	}
     
    	for (i = 0; i <= (lignefin-lignedebut) ; i++)
    	{
    		fgets(temp, sizeof(temp), fichier);
    		donnees[i] = (char *)malloc(sizeof(char)*strlen(temp));
    		strcpy(donnees[i], temp);
    	}
     
    	fclose(fichier);
    	return donnees;
     
    }
     
    // dans ta fonction principale:
     
    int i = 0;
    char ** meslignes = NULL;
    meslignes = lireligne(monfichier, lignedebut, lignefin);
    // traitement quelconque
    ....
    /* et on libère*/
    for(i=0; i< (lignefin - lignedebut); i++)
    {
         if(meslignes[i]) 
              free(meslignes[i]);
    }
    free(meslignes);

  7. #7
    Membre confirmé Avatar de crashtib
    Homme Profil pro
    Support technico-fonctionnel
    Inscrit en
    Avril 2009
    Messages
    221
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Support technico-fonctionnel
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 221
    Par défaut
    je m'emballe pas!

    merci pour ta solution gui. C'était pas propre en effet. Je pensais qu'il y avait moyen de faire avec sizeof, mais je me suis lamentablement planté.

    merci à tous en tout cas et bonne journée

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 21/05/2008, 08h38
  2. Réponses: 1
    Dernier message: 06/03/2007, 14h28
  3. Réponses: 1
    Dernier message: 24/05/2006, 20h47
  4. Les Bases de Données! tout un monde!!
    Par kikimnet dans le forum Bases de données
    Réponses: 3
    Dernier message: 29/04/2004, 18h26

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