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 :

stocker le contenu d'un fichier texte dans un tableau


Sujet :

C

  1. #1
    Membre actif
    Inscrit en
    Décembre 2005
    Messages
    251
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 251
    Points : 267
    Points
    267
    Par défaut stocker le contenu d'un fichier texte dans un tableau
    Bonsoir. J'ai un fichier texte que j'aimerai stocker dans un tableau de chaine de caractère.

    Le fichier texte est de la forme suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    ligne 1
    ligne 2
    ligne 3
    ligne 4 
    ligne 5 
    ligne 6
    ligne 7
    Voici le code de mon programme. J'ai enlevé tout ce qui était controle d'erreur pour aller à l'essentiel. Je programme sous linux.
    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
     
       #include<stdio.h>
       #include<stdlib.h>
    int main()
    {
     
         FILE * fp=fopen("fichier.txt","r");
         int i=0; // pour recuperer la taille du tableau
     
         char** tab=(char**)malloc(10000*sizeof(char*));
        char* chaine=(char*)malloc(BUFSIZ*sizeof(char));
       //tableau dans lequel je   stocke le fichier
       // je ne suis pas sur de moi. Je mets 10 000 parce que je ne sais pas trop   //quoi mettre comme valeur max.
     //Je ne sais pas non plus si déclarer un char** de cette façon est correcte.
        while( fgets(chaine,BUFSIZ,fp)
       {
          *tab=chaine;
           i++;
           tab++;
       }
     
     //affichage du tableau
     
     
     
     
    }
    Et à l'affichage du tableau je bloque. Comment faire revenir le pointeur au début pour que je puisse le parcourir ?

    Merci d'avance

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Dans l'ordre:
    Probablement un pb dans la recopie:
    1/ Les includes devraient être situés en dehors du main
    2/ Il manque un '=' dans l'allocation de tab
    3/ Il manque une ')' à la fin du while.
    4/ Il manque les libérations
    Plus problématique:
    5/ *tab=chaine: Tu affectes toujours le même pointeur aux différentes entrées de ton tableau. Donc, toutes les entrées auront la même valeur, la dernière lue.
    6/Pour répondre à ta question,
    Comment faire revenir le pointeur au début pour que je puisse le parcourir ?
    Ne modifie pas le pointeur tab que tu as alloué, utilise un autre pointeur pour faire ton parcours.

  3. #3
    Membre actif
    Inscrit en
    Décembre 2005
    Messages
    251
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 251
    Points : 267
    Points
    267
    Par défaut
    1),2),3),4) sont bien des erreurs de recopie je corrige.


    Pour 5) je ne comprend pas trop. Vu que je lit le fichier avec fgets, la valeur de chaine change à chaque ligne lue non ?
    Puis si je fais un affichage de controle dans ma boucle sur chaine ce sont bien des lignes différentes qui s'affichent.

    Pour 6) exact je crorrige

    bon j'ai fait des modif. Voici mon nouveau code:

    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
     
     
      #include<stdio.h>
       #include<stdlib.h>
    int main()
    {
     
         FILE * fp=fopen("fichier.txt","r");
         int tailleTab=0; // pour recuperer la taille du tableau
     
         char** tab=(char**)malloc(10000*sizeof(char*));
        char* chaine=(char*)malloc(BUFSIZ*sizeof(char));
        char* res=(char*)malloc((BUFSIZ)*sizeof(char));
        char** temp=tab;
       //tableau dans lequel je   stocke le fichier
       // je ne suis pas sur de moi. Je mets 10 000 parce que je ne sais pas trop   //quoi mettre comme valeur max.
     //Je ne sais pas non plus si déclarer un char** de cette façon est correcte.
        while( res=fgets(chaine,BUFSIZ,fp)
       {
          *temp=res;
           tailleTab++;
           temp++;
       }
     
     //affichage du tableau
     
      while(j<=tailleTab)
      {
           printf("%s",*tab);
          tab++;
          j++;
     
      }
     
    return 0
    }//fin main
    Même probleme en faite. QUand j'affiche le tableau je n'affiche que la derniere ligne du fichier

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    1. Tu ne devrais jamais modifier tab: Utilise directement tab[j]
    2. Tu n'alloues qu'une seule chaîne, donc tu ne peux avoir qu'une seule ligne... Tu écrases toujours la chaîne.

  5. #5
    Membre actif
    Inscrit en
    Décembre 2005
    Messages
    251
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 251
    Points : 267
    Points
    267
    Par défaut
    Je ne comprend pas tres bien cette histoire d'allocation d'une seule chaine. Tu peux developper par l'exemple ? :s


    Parce que quand je fais :

    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
     
     
      #include<stdio.h>
       #include<stdlib.h>
    int main()
    {
     
         FILE * fp=fopen("fichier.txt","r");
         int tailleTab=0; // pour recuperer la taille du tableau
        int j=0;
         char** tab=(char**)malloc(10000*sizeof(char*));
        char* chaine=(char*)malloc(BUFSIZ*sizeof(char));
        char* res=(char*)malloc((BUFSIZ)*sizeof(char));
        char** temp=tab;
       //tableau dans lequel je   stocke le fichier
       // je ne suis pas sur de moi. Je mets 10 000 parce que je ne sais pas trop   //quoi mettre comme valeur max.
     //Je ne sais pas non plus si déclarer un char** de cette façon est correcte.
        while( res=fgets(chaine,BUFSIZ,fp))
       {
           printf("%s",chaine);
          temp[j]=chaine;
          j++;
       }
     
     //affichage du tableau
     tailleTab=j++;
     j=0;
      while(j<=tailleTab)
      {
           printf("%s",tab[j]);
     
          j++;
     
      }
     
    return 0
    }//fin main
    La partie affichage du tableau me renvoie toujours que la derniere ligne du tableau repeter 7 fois.

    Mais le printf("%s"',chaine) que j'ai rajouté dans le premier while m'affiche bien toutes les lignes de mon fichier.

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Tu alloues la place pour dix mille pointeurs, mais tu as seulement alloué deux tableaux de char...
    En clair, tes dix mille pointeurs ne pointent sur rien du tout au début, puis, tous ceux que tu affectes, tu les fais pointer sur le même tableau de char...

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par sneb5757 Voir le message
    La partie affichage du tableau me renvoie toujours que la derniere ligne du tableau repeter 7 fois.

    Mais le printf("%s"',chaine) que j'ai rajouté dans le premier while m'affiche bien toutes les lignes de mon fichier.
    C'était le sens de ma remarque 5 et de la précision de Medinoc.


    En fait, puisque tu fais un tableau de pointeur, chaque entrée de ton tableau devrait être alloué. Et c'est avec cette entrée que tu lis les données de ton fichier.

  8. #8
    Membre actif
    Inscrit en
    Décembre 2005
    Messages
    251
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 251
    Points : 267
    Points
    267
    Par défaut
    Ok donc c'est pas le meilleur moyen pour faire un tableau de chaine de caractère ?

    Vous pourriez pas me montrer un exemple c'est la panne sèche la.

    Edit : je pense que c'est bon


    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
     
     
    int main(int argc,char* argv [])
    {
          char** tab=(char**)malloc((10000)*sizeof(char*));
         char ** temp=tab;
        char* parcours=(char*)malloc((BUFSIZ)*sizeof(char));
        int tailleTab=0;
       int j=0;
       FILE * fp=fopen("fichier.txt","r");
       if(fp==NULL)exit(1);
     
       while(fgets(parcours,BUFSIZ,fp)!=NULL)
       {
            temp[j]=(char*)malloc((strlen(parcours))*sizeof(char));
            strcpy(temp[j],parcours);
            j++;
       }
     
      tailleTab=j;
      j=0;
     
     while(j<tailleTab)
     {
        printf("%s",tab[j]);
       j++
      }
    }
    ça s'affiche correctement. L'utilisation de la fonction strcpy au lieu de l'affectation classique solutionne le problème( je ne comprend pas trés bien pourquoi j'avoue).

    Mais j'ai un autre probleme. J'ai alloué de la mémoire. Je souhaite donc utilisé la fonction free sur les pointeurs que j'ai alloué :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    free(tab);
    free(parcours);
    J'ai une belle erreur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    glibc detected  ./nomProg : double free or corruption(!prev)

    Comment désalloué correctement ma mémoire ?

  9. #9
    Membre expérimenté Avatar de BainE
    Inscrit en
    Mai 2004
    Messages
    1 327
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 1 327
    Points : 1 544
    Points
    1 544
    Par défaut
    bonjour,

    le probleme n'est pas tant comment bien desallouer, mais comment bien utiliser la mémoire allouée, ne pas depasser de l espace qu on a reservé.

    c'est le sens du message :
    double free or corruption(!prev)

    soit tu essaye de desallouer 2 fois le meme pointeur, soit tu a jardiner dedans et free ne s y retrouve plus.

    P.S. : je vois ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char** tab=(char**)malloc((10000)*sizeof(char*));
    char ** temp=tab;
    free sur l un, c'est free sur l autre aussi, puisse qu'il contiennent la meme adresse, donc un seul free pour ces deux pointeur.

  10. #10
    Membre actif
    Inscrit en
    Décembre 2005
    Messages
    251
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 251
    Points : 267
    Points
    267
    Par défaut
    Merci de ta réponse.

    Mais si tu regardes bien mon code précédent je fais simplement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    free(tab);
    free(parcours);
    A aucun moment je ne fais un free sur temp. Donc je ne vois pas pourquoi il me met ce message.

  11. #11
    Membre expérimenté Avatar de BainE
    Inscrit en
    Mai 2004
    Messages
    1 327
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 1 327
    Points : 1 544
    Points
    1 544
    Par défaut
    si y a pas de double allocation, c'est que tu jardines la mémoire a coup de bêche édenté

    [edit]
    pour une liberation propre et complete :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
        for( j = 0; j < tailleTab; ++j )
        {
            free( tab[ j ] );
            tab[ j ] = NULL;
        }
     
        free( tab ), tab = NULL;
        free( parcours ), parcours = NULL;
    ca peut planter si :
    1- t as plus de 10 000 lignes
    2- une des lignes fait plus de BUFSIZ - 1 (qui semble faire 512 octets)
    3- un des malloc (dont aucun des retour n'est testé ) plante

  12. #12
    Membre actif
    Inscrit en
    Décembre 2005
    Messages
    251
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 251
    Points : 267
    Points
    267
    Par défaut
    bon ça marche en faite j'avais juste une erreur de recopie. Il me reste plus qu'a tester le retour des malloc. Voici mon code
    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
     
     
    int main(int argc,char* argv [])
    {
          char** tab=(char**)malloc((10000)*sizeof(char*));
         char ** temp=tab;
        char* parcours=(char*)malloc((BUFSIZ)*sizeof(char));
        int tailleTab=0;
       int j=0;
       FILE * fp=fopen("fichier.txt","r");
       if(fp==NULL)exit(1);
     
       while(fgets(parcours,BUFSIZ,fp)!=NULL)
       {
            temp[j]=(char*)malloc((strlen(parcours))*sizeof(char));
            strcpy(temp[j],parcours);
            j++;
       }
     
      tailleTab=j;
      j=0;
     
     while(j<tailleTab)
     {
        printf("%s",tab[j]);
       j++
      }
    }
     
     
     
     
    free(tab);
    free(parcours);

    j'ai quelques questions . Peut etre devrais -je ouvrir un autre thread si le probleme de base est résolu. Ca concerne la mémoire :

    1) Est ce que ma gestion est correcte ? Y a t'il un moyen de le vérifier ?

    2) Concernant le declaration de mon tableau de chaine de caractère :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     
       char** tab=(char**)malloc((10000)*sizeof(char*));
    le 10 000 me gène. Je ne pourrais pas lire fichiers de plus de 10 000 caractère. Et pour les fichiers de moins de 10 000 carac j'alloue trop de mémoire. C'est dommage. Il y'a t'il un moyen de contourner ça ? D'intuition je crois que je vais être obligé de faire une fonction qui parcours mon fichier et qui compte les lignes. Mais ça me fait parcourir deux fois un même fichier pour le stocker. C'est dommage.

  13. #13
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Tu peux jouer avec la fonction realloc(). Au début tu alloues 1000 lignes, quand tu arrives à la fin de tes 1000 lignes, tu doubles (2000) ton nombre de lignes avec realloc(). Si tu arrives encore à la fin de tes 2000, tu réalloues à 4000 etc.

Discussions similaires

  1. contenu d'un fichier texte dans un tableau
    Par lyoram dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 30/11/2006, 11h15
  2. Réponses: 4
    Dernier message: 15/08/2006, 17h40
  3. Réponses: 8
    Dernier message: 06/08/2006, 15h11
  4. Réponses: 3
    Dernier message: 19/05/2006, 11h35
  5. [Tableaux] Stocker un fichier texte dans un tableau
    Par clairette59 dans le forum Langage
    Réponses: 13
    Dernier message: 27/01/2006, 23h48

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