Erreur segementation en c

Résolu/Fermé
zdarbilo - 16 févr. 2009 à 23:34
 zdarbilo - 17 févr. 2009 à 13:49
Bonjour,
J'espere que quelqu'un pourra m'aider voici mon souci je cherche a creer une fonction qui lira dans un fichier ligne par ligne et stockera celle-ci dans un tableau , voici mon code :

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
FILE * f1,*f2;
char ligne[];
int i;
char *chaine[];



void lecture_fichier()
{

f1 = fopen("nom", "r"); // ouvrir en lecture
//f2 = fopen("place", "r");
if(f1 == NULL){
printf("Impossible d'ouvrir le fichier %s\n", "nom");
exit(1);
}
printf(".............. Ouverture du fichier %s\n", "nom");

int i=0;
printf("Liste des spectacles\n");
while(fgets(ligne, 255,f1) != NULL && i<20 ) {
strcpy(chaine[],ligne);
printf("%s",chaine[i]);
i++;
}


// fermeture du fichier
if(fclose(f1) == EOF /*|| fclose(f2) == EOF*/) {
printf("Probleme de fermeture du fichier %s", "nom");
exit(1);
}
printf(".............. Fermeture du fichier %s\n", "nom");

return 0;
}





main(){

lecture_fichier();
}



Le souci que je rencontre est que j'ai le message "erreur de segmentation" à la compilation . Merci de m'aider car la je patoge .

4 réponses

C'est toujours la même histoire... Problème de segmentation --->>> à 99%, c'est un problème de pointeur!!!
Je comprends que beaucoup de gens ne conseille pas le C aux débutants.
Lorsqu'on choisit le C, il faut savoir que c'est un langage rapide et adaptable à toute situation, mais qu'en contrepartie, il demande une grande exigence et, si on ne l'est pas, il faut en choisir un autre, il n'y a pas de honte (tout le monde ne peut pas conduire une formule 1); il y a aujourd'hui d'excellents langages qui sont beaucoup plus facile à apprendre.
Tu utilises deux pointeurs (je ne parle pas des FILES*) et tous les deux sont mal utilisés.
Bon courage et ne m'en veux pas mais c'est une erreur tellement récurente ;-)
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 841
17 févr. 2009 à 02:16
Salut,
Effectivement, pas mal de maladresses.
Tout d'abord, pas de variables globales, sauf cas particuliers.
Pas de : char toto[]; sans définir la taille. Soit tu connais la taille, et tu la mets, soit tu passes par un pointeur dont t'alloueras la zone à l'exécution et que tu désalloueras lorsque tu n'en auras plus besoin.
Petite subtilité dans ta boucle while : mets la condition sur i avant.
while(i<20 && fgets...)
et non
while(fgets() && i<20);

Je t'ai corrigé ton programme. Tu peux récupérer le tableau de pointeurs dans ton main. Je pense que c'est ce que tu voulais faire avec tes variables globales.
Si tu as des questions sur le code, n'hésite pas.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MAX 20
#define LENGTH 256
#define PATH "nom"

int lecture_fichier(char *chaine[MAX])
{
    FILE *f1;
    char ligne[LENGTH];
    int i;

    f1 = fopen(PATH, "r"); /* ouvrir en lecture*/
    if(f1 == NULL){
        fprintf(stderr,"Impossible d'ouvrir le fichier %s\n",PATH);
        exit(1);
    }

    printf(".............. Ouverture du fichier %s\n", PATH);

    i=0;
    printf("Liste des spectacles\n");
    while(i<MAX && fgets(ligne, sizeof ligne,f1) != NULL) {
        size_t s;

        char *p=strchr(ligne,'\n');
        if(p) *p='\0';

        s=strlen(ligne)+1;
        if(s>LENGTH) s=LENGTH;

        chaine[i]=malloc(s);
        if(chaine[i] == NULL) {
            fputs("Erreur d'allocation\n",stderr);
            exit(1);
        }

        strncpy(chaine[i],ligne,s);
        i++;
    }
    /* fermeture du fichier*/
    if(fclose(f1)==EOF){
        fprintf(stderr,"Probleme de fermeture du fichier %s\n",PATH);
        exit(1);
    }

    printf(".............. Fermeture du fichier %s\n",PATH);

    return i;
}


int main(void){
    char *chaine[MAX];
    size_t sz=lecture_fichier(chaine);
    size_t i;


    /*affichage*/
    for(i=0;i<sz;i++)
        puts(chaine[i]);

    /*libération des ressources*/
    for(i=0;i<sz;i++)
        free(chaine[i]),chaine[i]=NULL;
    
    return 0;
} 

0
Salu fiddy, je te remercie d'avoir modifier mon code par contre il y'a quelques lignes que je ne comprends pas .
celle-ci :

char *p=strchr(ligne,'\n');
if(p) *p='\0';


et celle la:


chaine[i]=malloc(s);


Merci de ton aide.

PS :loupius je suis la pour apprendre je ne te force pas a m'aider mais je ne pense pas que toi meme tu ais appris le c sans aide et sans faire d'erreurs,je me doute que voir la meme erreur sur plusieurs sujet est ennervant. Merci quand meme pour ta piste.
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 841
17 févr. 2009 à 11:37
Une fin de ligne dans un fichier contient un \n (voir même \r\n). Donc, l'idée est de l'enlever.
char *p=strchr(ligne,'\n');
if(p) *p='\0'; 

Première ligne, p contiendra l'adresse du premier \n trouvé dans le tableau ligne, NULL s'il n'existe pas.
Deuxième ligne, on le remplace par \0.

chaine[i]=malloc(s); 

Là c'est primordial lorsque tu fais des tableaux dynamiques. chaine[j] est un pointeur. Pour qu'il puisse accueillir des données, il faut allouer une zone dans le heap. malloc(s) justement va allouer cette zone de s char. (pas besoin de multiplier par sizeof(char), car ça vaut 1).
Et le free à la fin, c'est pour désallouer cette zone. Ca évite les fuites mémoires.
0
Ok merci pour ton aide c'etait tres precis et ca m'a beaucoup aidé .
A bientot j'espere.
0