Segmentation fault dans un programme C
macha
-
fiddy Messages postés 11069 Date d'inscription Statut Contributeur Dernière intervention -
fiddy Messages postés 11069 Date d'inscription Statut Contributeur Dernière intervention -
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;
}
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;
}
A voir également:
- Segmentation fault dans un programme C
- Programme demarrage windows - Guide
- Cette action ne peut pas être réalisée car le fichier est ouvert dans un autre programme - Guide
- Mettre en veille un programme - Guide
- Forcer la fermeture d'un programme - Guide
- Message programmé iphone - Guide
2 réponses
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 :
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
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