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 :

Parcourir un fichier


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    Par défaut Parcourir un fichier
    Bonjour; bonsoir,

    je viens vous voir pour quelque chose de somme toute assez basique mais que j'aimerais voir noir sur blanc. =)

    Le but; lire un fichier ( à priori avec une boucle tant que !EOF)

    EN commençant ligne par ligne, puis mot par mot pour finir éventuellement caractère par caractère.


    Je pense qu'une première méthode serait d'employer fgets et de compter en sommes les espaces ou ce genre de choses; mais ça ne me parait pas très fiable.
    J'ai pas trouvé la page parlant de cela sur le site. Autrement pour les mots on peut boucler sur \0 ?

    Donc au final un fichier sera structuré un peut comme ça ?

    mot1\0 mot2\0 \n
    mot3\0 \n
    EOF

    Comment procéderiez vous pour faire cela ?

    Merci à vous !

  2. #2
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    Par défaut
    Par exemple;

    Imaginons un programme qui lise un fichier (pour simplifier, j'ai considéré que je n'avais qu'un seul mot par ligne)


    Voilà ce que j'ai fait; qu'en pensez vous ?

    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
    void frequenceMot(FILE *f)
    {
    	f=fopen("rep.txt","r");
    	char chaine[TAILLE_MAX]="";
    	char* tabMot[TAILLE_MAX]={""};
    	if(f != NULL)
    	{
    		int k=0;
    		while (fgets(chaine, TAILLE_MAX, f) != NULL) // On lit le fichier tant qu'on ne reçoit pas d'erreur (NULL)
    		{
    			tabMot[k]=calloc(TAILLE_MAX,sizeof(char));
    			if (tabMot[k]==NULL)
    			{
    				fprintf(stderr, "Erreur calloc\n");
    				exit(1);
    			}
    			strcpy(tabMot[k],chaine);
    			k++;
    			printf("%s\n",chaine);
    			printf("%s\n",tabMot[k]); //segfault
    		}
    	}
    }
    Ici, je pense que si je me suis pas planté je devrais lire les lignes du fichiers en entier.
    L'affichage me montre que chaine prend bien la valeur de ma première ligne du fichier.

    Je veux alors stocké cette chaîne dans un tableau de chaines que j'aurais alloué au préalable. Mais je prend quand même une erreur de segmentation sur l'affichage de tabMot[k]; sous entendu, la copie avec strcpy n'a pas été effectué correctement ! Je n'arrive pas à régler ce problème.

  3. #3
    Membre habitué
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2013
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Octobre 2013
    Messages : 11
    Par défaut
    Ton probleme de segmentation vient surement de ta chaine oú tu copie qui doit etre trop courte
    Pour lire ton fichier ligne par ligne , lit le jusqu'à un \n grace a un fgetc et une boucle par exemple (fait attention a la longueur de ta chaine)

    mot par mot grace au meme principe et caractere par caractere grace a fgetc
    le principe maintenant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int nb_caractere_lu = 0, taille_chaine = 100, caractere = 0 ;/* c'est un exemple, la taille peut etr plus grande */
    char chaine[taille_chaine] = {0};
    while( nb_caractere_lu < 100 && caractere != EOF)
    {
    caractere = fgetc(ton_fichier);
    chaine[nb_caractere_lu] = caractere;
    nb_caractere_lu++;
    }
    Voila le principe de base, j'espere qu'il t'aidera
    attention ne copie colle pas ça betement j'ai surement du faire plein de faute de typo (sur un mini telephone c'est dur !)

  4. #4
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    Par défaut
    Pourtant je vois mal comment le soucis peut venir de là.

    fgets prend la chaine en lui donnant une taille maximum.
    Et la chaîne de copie à la même taille max en paramètre (j'ai tenté d'augmenté cette taille de 1 pour être sur tout de même) mais l'erreur de segmentation reste présente.

    EDIT; bon alors après vérification il s'agit bien de la taille; j'ai affiché la taille de chaine qui est de 8 "Bonjour\0"; mais la taille de mon tableau à l'indice k est de 0.
    Je ne comprends pas pourquoi, je fais bien un calloc au préalable et il ne plante pas puisque je ne rentre pas dans le if !!!
    J'avoue ne pas comprendre !

    La ligne tabMot[k]=calloc(TAILLE_MAX+1,sizeof(char)) devrait me retourner une taille positive hors la taille est de 0


    Le comportement est en fait assez étrange.

    Après le calloc/malloc la longueur du tableau est de 0 (Alors que ça devrait être 51 sachant que TAILLE_MAX est un define sur 50).
    Après le strcpy la longueur du tableau est bel et bien la même que celle de chaîne; sous entendu la copie c'est bien passé puisque même longueur; pourtant l'erreur de segmentation persiste !

    EDIT 3

    J'ai résolu si je puis dire l'erreur dans le sens ou je vois ce qui l'a provoque; mais je n'ai aucune idée de la raison de ce "bug"

    Mon affectation est bonne en réalité et l'affichage se passe bien. SI et seulement si je ne fais pas d'affichage avant.

    C'est à dire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    strcpy(tabMot[k],chaine);
    			k++;
    			printf("%s\n",chaine);
    			printf("test\n");
    			printf("%s\n",tabMot[k]);
    n'affichera que chaine puis prend une core dumped sur tabMot

    Mais si je prend la même structure en sautant les affichages précédent; plus rien et le prog s'exécute normalement !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    strcpy(tabMot[k],chaine);
    			k++;
    			printf("%s\n",tabMot[k]);
    Donc voilà; ceci m'affiche bien les chaines copiés.


    Mais si quelqun est en mesure de m'expliquer pourquoi le fait de faire un affichage au préalable me provoque une erreur ça serait cool =)

  5. #5
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
                tabMot[k]=calloc(TAILLE_MAX,sizeof(char));
                if (tabMot[k]==NULL)
                {
                    fprintf(stderr, "Erreur calloc\n");
                    exit(1);
                }
                strcpy(tabMot[k],chaine);
                k++; // !!!!!!!
                printf("%s\n",chaine);
                printf("%s\n",tabMot[k]); //segfault
    Tu alloues à l'indice k, tu copies, tu incrémentes k et tu essayes d'accéder à un pointeur non alloué…

    D'ailleurs chez moi, voilà ce qui se passe quand j'appelle ta fonction :
    $ gccw test.c && ./a.out test.c: In function 'main':
    test.c:35:14: warning: 'fichier' is used uninitialized in this function [-Wuninitialized]
      frequenceMot(fichier);
                  ^
    bonjour
    
    
    (null)
    developpez
    
    
    (null)
    .com
    
    
    (null)
    
    $ cat rep.txt bonjour
    developpez
    .com
    Je ne sais pas ce que ca affiche chez toi, mais tu devais voir quelque chose de louche, non ?
    Quand tu veux afficher des chaines comme ça, il ne faut pas hésiter à mettre des marques plus clairs. 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
    void frequenceMot(FILE *f){
    	f=fopen("rep.txt","r");
    	char chaine[TAILLE_MAX]="";
    	char* tabMot[TAILLE_MAX]={""};
    	if(f != NULL)
    	{
    		int k=0;
    		while (fgets(chaine, TAILLE_MAX, f) != NULL) // On lit le fichier tant qu'on ne reçoit pas d'erreur (NULL)
    		{
    			tabMot[k]=calloc(TAILLE_MAX,sizeof(char));
    			if (tabMot[k]==NULL)
    			{
    				fprintf(stderr, "Erreur calloc\n");
    				exit(1);
    			}
    			strcpy(tabMot[k],chaine);
    			printf("Lu {%s}\nSauve [%s]\n\n",chaine, tabMot[k]); // nouvelle façon
    			k++; // correction
    		}
    	}
    }
    Ce qui donne :
    gccw test.c && ./a.out test.c: In function 'main':
    test.c:34:14: warning: 'fichier' is used uninitialized in this function [-Wuninitialized]
      frequenceMot(fichier);
                  ^
    Lu {bonjour
    }
    Sauve [bonjour
    ]
    
    
    Lu {developpez
    }
    Sauve [developpez
    ]
    
    
    Lu {.com
    }
    Sauve [.com
    ]

Discussions similaires

  1. Comment parcourir un fichier texte avec une boucle ?
    Par kikica dans le forum Langage
    Réponses: 2
    Dernier message: 15/11/2005, 17h13
  2. Parcourir un fichier HTML
    Par obelix dans le forum Entrée/Sortie
    Réponses: 16
    Dernier message: 14/11/2005, 20h24
  3. [débutant]Parcourir un fichier XML
    Par Wis dans le forum ASP
    Réponses: 2
    Dernier message: 26/09/2005, 10h04
  4. Parcourir un fichier
    Par sepsep dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 27/07/2005, 08h25
  5. Réponses: 6
    Dernier message: 23/12/2003, 15h30

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