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 un fichier texte dans une liste


Sujet :

C

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 6
    Points : 2
    Points
    2
    Par défaut stocker un fichier texte dans une liste
    Bonjour!
    En fait j'ai un program a faire, qui consiste a ouvrir un fichier, et inserer les mots du texte un par un dans les noeuds d'une liste chainee. Je voulais creer une fonction readData() qui ouvre le fichier, et ensuite les fonctions classiques d'une lise (insertion...) voila un example du 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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #define ARRAY_SIZE 15
     
     
     
     
    typedef struct L {
    	char *str;
    	struct L *next;
    	}list;
     
    char *readData( char *string) {
    	FILE *fichier = NULL;
    	int letter = 0;
    	int i = 0;
    	fichier = fopen("christmas_carol.txt", "r");
               void rewind(FILE *fichier);
                 if (fichier != NULL) {
    		letter = fgetc(fichier);
    	  while ( letter!= EOF && letter != ' ' && letter!= '\n') {
    		letter = fgetc(fichier);
    		string[i] = letter;
    		i++;
    		letter = fgetc(fichier);}
     
    	fclose(fichier);
    	} return string;
    	}
     
    list *insertList(list *t, char *chaine) {
    	list *liste = calloc(1, sizeof(list));
    	liste->str = chaine;
    	liste->next = t;
    	return liste;
    	}
     
    list *somelist() {
    	list *w = NULL;
    	char *s = "";
    	s = readData(s);
    	  while (w != NULL) {
    	w = insertList(w, s);
    	  }
    	return w;
    	}
     
    int main() {
    	list *z = somelist();
    	while (z!= NULL) {
    	printf(z->str);
    	z = z->next;
    	}
    	return 0;
    	}
    en fait le program n'affiche rien. Je voudrais savoir comment est-ce que je peux faire pour prendre le fichier en parametre et l'inserer avec ma fonction insertList(). Je n'ai rien trouvee d'autre que de renvoyer un char avec les lettres copiees une part une, mais le program ne marche pas.
    Si quelqu'un pouvais maidez..? merci

  2. #2
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Points : 1 351
    Points
    1 351
    Par défaut
    Salut,

    Le moyen le plus simple de sélectionner un fichier par son nom, c'est de passer son nom en paramètre à ton application. argc est le nombre d'arguments, argv[0] est le nom de ton application et argv[1] est le premier paramètre que tu as passé. Si ton application s'appelle "main.c" et ton fichier "monfichier.txt", le petit bout de programme ci dessous t'affichera

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    main.c
    monfichier.txt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <stdio.h>
    #include <stdlib.h>
    int main(int argc, char** argv)
    {
        int index = 0;
        while(index < argc)
        {
            printf("%s\n", argv[index]);
            index++;
        }
        return 0;
    }
    A+

    Pfeuh

  3. #3
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Dans somelist(), s est défini comme l'adresse d'un tableau non modifiable comportant 1 caractère ('\0')
    Il est passé à readData() dans lequel
    1- il est modifié alors que c'est interdit : string[i] = letter;
    2- il déborde largement la taille du tableau : l'accès est limitée à la lecture de string[0]


    Il faut définir dans somelist() un tableau accessible en écriture et suffisamment grand :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char s[256] = "";
    readData(s);
    Mais comme après tu appelle insertList() où l'adresse de ce tableau va être stockée dans la liste (liste->str = chaine) tu vas avoir un problème parce que le tableau sera détruit en sortie de somelist() et tu auras l'adresse d'une variable qui n'existe plus. Il faut assurer la survie du tableau en sortie de somelist(). La solution est l'allocation dynamique pour s :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char * s = malloc(......)
    readData(s);

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    merci pour les conseils. J'ai effectivement ouvert le fichier en le prenant en parametre dans main(), mais maintenant j'ai du mal avec ma fonction readData.. est-ce-qu'elle peut prendre un fichier en parametre? comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    char *readData( FILE *doc) {
    	int letter = 0;
    	char *string[200000] = "";
    	int i = 0;
                 if (doc != NULL) {
    		letter = fgetc(doc);
    	  while ( letter!= EOF && letter != ' ' && letter!= '\n') {
    		string[i] = letter;
    		i++;
    		letter = fgetc(fichier);}
     
    	fclose(doc);
    	} return string;
    	}
    parce-que je dois obligatoirement creer une fonction de lecture car je m'en servirait por inserer le texte dans une table de hachage.

    Et diogene, j'avais effectivement un probleme d'allocation, mais maintenant que readData ne prend plus une chaine en parametre, je ne peut plus la copier dans somelist():

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    list *somelist() {
    	list *w = NULL;
    	char *s = malloc(sizeof(char));
    	readData(s);
    	  while (w != NULL) {
    	w = insertList(w, s);
    	  }
    	return w;
    	}
    ma fonction main ressemble a sa:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int main( int argc, char *argv) {
    	FILE *fichier = NULL;
    	if (argc>1) {
    	    fichier = fopen(argv[1], "r");}
    	readData(fichier);
    	     list * z = somelist();
    	while (z != NULL) {
    	   printf("%s",z->str);
    	   z = z->next;
    	}
    	return 0;
    	}
    j'ai l'impression d'aller dans la mauvaise direction...

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Apres des heures de codages, voila ce a quoi je parviens... ce qui devrais fonctionner a mon avis, mais mon main() n'affiche rien.. ma liste a toujours l'air d'etre vide...
    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
    typedef struct L {
    	char *str;
    	struct L *next;
    	}list;
     
     
     
    char *readData( FILE *doc, char str[ARRAY_SIZE]) {
    	int letter = 0;
    	char chaine[ARRAY_SIZE] = "";
    	int i = 0;
    	//char *string = str;
                 if (doc != NULL) {
    		letter = fgetc(doc);
    	   fgets(chaine,ARRAY_SIZE, doc);
    		strcpy(str, chaine); 
                   } return str;
     
    list *insertList(list *t, char *chaine) {
    	list *liste = calloc(1, sizeof(list));
    	liste->str = chaine;
    	liste->next = t;
    	return liste;
    	}
     
    list *somelist(FILE *doc2) {
    	list *w = NULL;
    	char *s = malloc(sizeof(char));
    	  while (w != NULL) {
    	    readData(doc2, s);
    	     w = insertList(w, s);
    	  }
    	return w;
    	}
     
    int main( int argc, char *argv[]) {
    	FILE *fichier = NULL;
    	char ch[ARRAY_SIZE] = "";
    	if (argc>1) 
    	{
    	    fichier = fopen(argv[1], "r");
    	}
    	readData(fichier, ch);
    	     list * z = somelist(fichier);
    	while (z != NULL) {
    	   printf("%s",z->str);
    	   z = z->next;
    	}
    	return 0;
    	}
     
    	}

  6. #6
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Procédons par ordre :

    main() :
    A quoi sert ch[] ? Il est rempli par l'appel à readData() et ensuite totalement inutilisé. Est-ce que c'est pour sauter la première ligne du fichier ?

    readData() :
    A quoi servent i et letter ? Ils sont inutilisés. Pourquoi lire le fichier dans chaine pour copier ensuite dans str ? Pourquoi ne pas écrire directement dans str ? Pourquoi retourner str ? Puisque c'est l'appelant qui passe ce paramètre, il sait parfaitement ce qu'il est et n'a pas besoin qu'on le lui rappelle.
    Tout bien pesé, il semble que cette fonction puisse se résumer à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char *readData( FILE *doc, char str[ARRAY_SIZE]) 
    {
       if (doc != NULL) return  fgets(str,ARRAY_SIZE, doc);
       return NULL;
    }
    fonction qui retourne alors NULL en cas d'erreur ou de fin de fichier.

    somelist() :
    Le tableau alloué à s n'a qu'un caractère, de quoi stocker le zéro terminal et pas plus. s ne peut donc stocker qu'une chaine vide !
    L'ennui est qu'on ne connait pas à ce stade la taille de la chaine à allouer, puisqu'on la récupère ultérieurement par readData(). Il semble qu'il faille réordonner ce code et de demander à readData() de faire cette allocation et de renvoyer la chaine lue dans le tableau qu'il aura alloué lui-même. Par exemple :
    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
    char *readData(FILE *doc) 
    {
       char chaine[ARRAY_SIZE] ; // tableau temporaire
       char * p = NULL;  
       if(doc != NULL && fgets(chaine,ARRAY_SIZE, doc)!= NULL) // lire une ligne
       {
          p = strchr(chaine,'\n'); // supprimer le caractère de fin de ligne...
          if(p!=NULL) *p = '\0';   // ...présent dans chaine
          p = malloc(strlen(chaine)+1);  // allouer la quantité nécessaire et suffisante...
          if(p!=NULL) strcpy(p,chaine);  // ...pour copier la chaine si l'allocation a réussi
       }
       return p; // retourne la chaine ou NULL en cas d'échec...
    }            // ...(erreur de lecture, fin de fichier, erreur d'allocation)
     
    list *somelist(FILE *doc) 
    {
       list *w = NULL;
       char * chaine;
       do
       {
         chaine = readData(doc);   //récupérer les chaines
         if(chaine != NULL)  w = insertList(w, chaine);  // les mettre dans la liste
       } while(chaine != NULL);    //tant qu'il y en a 
       return w;
    }
    Les choses devraient aller mieux. Toutefois, la liste comportera les chaines dans l'ordre inverse de la lecture. Si on veut les avoir dans le bon ordre, il faut revisiter insertList().

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    En fait comme je ne savais pas comment faire pour que readData() renvoi une chaine, j'ai donc creer une chaine qui passe comme parametre de readData. Dans main il me fallait donc creer une liste vide qui est char ch[] porpouvoir appeler la fonction readData().
    Mais vraiment merci, parce-que j'etais toujours confuse quand a la creation d'une chaine de caractere.. quand je definissait dans la fonction, gcc renvoi error, parce-que je n'ai pas le droit de renvoyer l'addresse d'une variable locale...
    Mais vraiment merci, ca marche maintenant. et pour insertList(), je l'ai definie comme : inserer en fin de liste..

    Merci!

Discussions similaires

  1. Réponses: 5
    Dernier message: 09/09/2011, 23h07
  2. Réponses: 2
    Dernier message: 12/05/2010, 14h57
  3. Charger fichier texte dans une liste ?
    Par bahamut100 dans le forum C
    Réponses: 3
    Dernier message: 08/12/2009, 14h34
  4. importer fichiers texte dans une liste
    Par mcalus dans le forum Général Python
    Réponses: 7
    Dernier message: 29/01/2009, 14h17
  5. Insertion d'un fichier texte dans une moulinette PL/SQL
    Par Douanier007 dans le forum PL/SQL
    Réponses: 3
    Dernier message: 24/01/2005, 16h08

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