Segmentation fault dans un programme C

Fermé
macha - 31 oct. 2008 à 20:07
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 - 2 nov. 2008 à 00:21
Bonjour,
mon programme ci-dessous à partir d'un fichier texte où chaque ligne contient un nom et un numéro représentant la promotion de l'élève, calculer la moyenne de chaque promotion. On suppose que le nombre de promotions différentes contenus dans le fichier texte sera connue à l'avance.

Le programme ci-dessous est compilé; par contre à la compilation il fait un segmentation fault immédiatement. Est-ce que vous pouvez me dire ce qui ne va pas dans mon programme?

Merci d'avance.

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

#define ELEVES "eleves.txt"
#define NOMBREPROMOS 10

struct eleve{
char nom[129];
int num_promo;
};

struct promotion{
int num_promo;
int nombre_de_note;
int somme_des_notes;
int moyenne;
};

//fonction pour ouvrir le fichier//
FILE *ouvrir_fichier(char *nom_fichier)
{
FILE *fd= fopen(nom_fichier,"r");
return fd;
}

//fonction qui lit une ligne d'un fichier//
//la ligne est du fichier texte est de format nom num_promo//
//la fonction met dans la structure eleve ce qu'elle a trouvé dans le fichier//

int lire_eleve(struct eleve *un_eleve,FILE * fichier)
{
int retour_lire_eleve;
int retour_fscanf;
retour_fscanf=fscanf(fichier,"%s %d",un_eleve->nom,&(un_eleve->num_promo));
if (retour_fscanf==0)
{
retour_lire_eleve=0;
}
else
{
retour_lire_eleve=-1;
}
return retour_lire_eleve;
}

//fonction qui permet de donner à un élève une note entre 0 et 20//
int tirage()
{
int nombre;
printf("donnez un nombre entre 0 et 20");
scanf("%d",&nombre);
return nombre;
}

//fonction qui calcule la moyenne de toutes les promotions//
// on reprèsente les nb promotions par un tableau de nb struct promotion//
//prend en parametre le nb de promotion et renvoie un tableau de nb struct promotions//

struct promotion *calcul_moyenne_promo(int nb)
{

struct promotion *tab_promotion;
tab_promotion=calloc(nb,sizeof(struct promotion));

FILE *fd=ouvrir_fichier(ELEVES);

int termine=0;
struct eleve *un_eleve;
int fin_fichier;
int i;
int trouve=0;

//initialisation du tableau de promotion//
for (i=0;i<nb;i++)
{
tab_promotion[i].num_promo=0;
tab_promotion[i].nombre_de_note=0;
tab_promotion[i].somme_des_notes=0;
tab_promotion[i].moyenne=0;
}

while (!termine)
{
fin_fichier=lire_eleve(un_eleve,fd);
if (fin_fichier==0)
{
termine=1;
}
//si on n'est pas encore à la fin du fichier
else
{
//tant qu'on a pas trouve dans le tableau que la promotion de l'élève est déjà existente
while (!trouve && i==nb-1)
{
if (tab_promotion[i].num_promo==un_eleve->num_promo)
{
trouve=1;
(tab_promotion[i].nombre_de_note)++;
(tab_promotion[i].somme_des_notes)+=tirage();
}
i++;
}
//si le numéro de la promo n'existe pas encore dans le tableau des promotions, on modifie le premier numéro de promotion encore à 0//
if (trouve==0)
{
while (tab_promotion[i].num_promo != 0)
{
i++;
}
tab_promotion[i].num_promo=un_eleve->num_promo;
(tab_promotion[i].nombre_de_note)++;
(tab_promotion[i].somme_des_notes)+=tirage();
}
}
}
//calcule la moyenne pour chaque promotion c.a.d pour chaque case du tableau
for (i=0;i<nb;i++)
{
tab_promotion[i].moyenne=tab_promotion[i].somme_des_notes/tab_promotion[i].nombre_de_note;
}
return tab_promotion;
}
void affichage(struct promotion *tab_promotion)
{
int i;
for (i=0;i<NOMBREPROMOS;i++){
printf("voici la promo %d:\n",tab_promotion[i].num_promo);
printf("la moyenne de cette promo %d:\n",tab_promotion[i].moyenne);
}
}
int main(void)
{
printf("a");
struct promotion *tab_promos_test;
tab_promos_test=calcul_moyenne_promo(10);
affichage(tab_promos_test);
return 0;
}

2 réponses

fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
31 oct. 2008 à 21:01
Salut,
Avant de poster, merci d'utiliser les balises de code (à droite de souligner) pour garder l'indentation car c'est illisible.
Sinon, ton code donne un segfault car tu n'as pas le fichier eleves.txt de créer dans le répertoire courant. Voilà pourquoi, il faut toujours vérifier les valeurs de retour.
Du genre :
FILE *fp;
if((fp=fopen(...)) ==NULL){ puts("erreur"); exit(-1);

Comme ça, ça évite les bugs, et en plus ça t'aide à savoir d'où vient l'erreur.

Rem : Ton code contient peut-être des erreurs, j'ai juste regarder pour le segfault comme demandé ;)
Cdlt
0
Le truc c'est que j'avais bien créé un fichier eleves.txt dans le répertoire courant quand j'ai testé ce programme. donc je me dis que ça doit venir d'ailleurs...
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
2 nov. 2008 à 00:21
Oui, mais en informatique, "se dire" ne suffit pas. Il faut être sûr. Donc mets le code que je t'ai mis à la place du tien, et poste le résultat que tu obtiens à l'exécution.
0