[C] petit problème avec fwrite et fread (resolu)

petit problème avec fwrite et fread (resolu) [C] - C++ - Programmation

Marsh Posté le 10-01-2003 à 19:44:44    

j'ai un peu de mal avec les fonctions fread et fwrite. Je m'en sers pour enregistrer un tableau de flottants (ici notes) de NBELEVES éléments dans un fichier.
 
Bon le problème c'est que l'execution me rend toujours "segmentation fault" , et je ne vois pas bien d'où ça peut venir. il me semble bien que les paramètres que je passe à fwrite sont correctes, d'après le prototype de cette fonction : size_t   fwrite(const  void  *ptr,  size_t  size,  size_t  nmemb,  FILE *stream);
 
j'ai un autre bout de code similaire avec fread, et j'ai la meme erreur.
je suis sous mandrake 9.0, compilateur gcc.
 
 

Code :
  1. #define NBELEVES 5
  2. ...
  3. float notes[NBELEVES] ;
  4.   FILE* F;
  5. char *nomFichier;
  6.   printf("Quel est le nom du fichier où vous voulez sauvegarder ?\n" );
  7.   while ( EOF == scanf("%s",&nomFichier[0]) ) 
  8.     printf("veuillez refaire une saisie svp\n" );
  9.  
  10.   F=fopen(nomFichier,"w" );
  11.       if (F==NULL)
  12.          printf("erreur d'ouverture du fichier !\n" );
  13.  
  14.   if (NBELEVES != fwrite(notes,4,NBELEVES,F))
  15.           printf("erreur d'écriture dans le fichier !\n" );

 
 
merci de bien vouloir m'aider


Message édité par mani le 10-01-2003 à 21:49:59
Reply

Marsh Posté le 10-01-2003 à 19:44:44   

Reply

Marsh Posté le 10-01-2003 à 19:53:18    

tu peux donner du code plus complet s'il te plait?

Reply

Marsh Posté le 10-01-2003 à 19:59:12    

ben voilà je peut pas faire plus précis sur le code :D

Reply

Marsh Posté le 10-01-2003 à 20:03:51    

en fait ce qui m'aurait interesse c'est la délcaration de nomfichier
 
edit: attention, il manque un fclose dans le case '9'
 
dans tes read ou write préfère par exemple (sizeof float) plutot que (4)


Message édité par Taz le 10-01-2003 à 20:06:40
Reply

Marsh Posté le 10-01-2003 à 20:06:31    

++Taz a écrit :

en fait ce qui m'aurait interesse c'est la délcaration de nomfichier


 
OK fallait le dire : j'édite ...

Reply

Marsh Posté le 10-01-2003 à 20:07:09    

mani a écrit :

j'ai un peu de mal avec les fonctions fread et fwrite. Je m'en sers pour enregistrer un tableau de flottants (ici notes) de NBELEVES éléments dans un fichier.
 
Bon le problème c'est que l'execution me rend toujours "segmentation fault" , et je ne vois pas bien d'où ça peut venir. il me semble bien que les paramètres que je passe à fwrite sont correctes, d'après le prototype de cette fonction : size_t   fwrite(const  void  *ptr,  size_t  size,  size_t  nmemb,  FILE *stream);
 
j'ai un autre bout de code similaire avec fread, et j'ai la meme erreur.
je suis sous mandrake 9.0, compilateur gcc.
 
 

Code :
  1. FILE* F;
  2. printf("Quel est le nom du fichier où vous voulez sauvegarder ?\n" );
  3. while ( EOF == scanf("%s",&nomFichier[0]) )
  4.  printf("veuillez refaire une saisie svp\n" );
  5. F=fopen(nomFichier,"w" );
  6.    if (F==NULL)
  7.     printf("erreur d'ouverture du fichier !\n" );
  8. if (NBELEVES != fwrite(notes,4,NBELEVES,F))
  9.       printf("erreur d'écriture dans le fichier !\n" );

 
 
merci de bien vouloir m'aider


 
avant toute chose, en cas de segmentation fault, utilise gdb.
Un début :
compiles et linke ton programme avec -g3 (au pire -g) en virant les -Omachin (si c'est possible, sur palmos, c'est rarement possible par ex.), ça va activer les infos de débuggage et virer les optimisations (qui compliquent ou empèchent le débuggage).
 
tu lances "gdb tonprog" au shell.
tu tappes "run <les arguments de ton prog>"
 
au moment du crash, gdb va te rendre la main, il sera dans l'état où c'est produit le crash.
 
tu tappes "bt" et il va t'afficher la pile des appels de fonctions avec les fichier et numéros de lignes.
 
tu tappes "up" pour remonter d'un cran (et voir un peu ce qui s'y passe) et "down" pour descendre d'un cran dans la pile des appels.
"list" pour voir le code
"print nom_var" pour voir une variable.
"help" pour avoir de l'aide.
 
le principe est : au moment du crash, tu cherches la dernière fonction à toi qui a été appelée dans la pile, tu montes dedans et tu regarde un peu l'instruction qui a provoqué le crash, les varibles qui sont dans le coin etc., si tu trouve une valeur anormale, elle a peut-être été passé en paramètre depuis la fontion du dessus donc tu remontes etc.
 
pour aller plus loin : http://sources.redhat.com/gdb/onlinedocs/gdb_toc.html
 
regarde avec gdb si c'est bien la fonction fwrite qui plante.
 
Evite les nom de variable en majuscules, on les garde pour les macros.
 
Sinon, il sort d'où ton 4 dans fwrite ? à cet endroit on met généralement des sizeof(machin) enfi des trucs mesurés en nombre d'octets

Reply

Marsh Posté le 10-01-2003 à 20:09:31    

++Taz a écrit :

en fait ce qui m'aurait interesse c'est la délcaration de nomfichier
 
 


 
t'as le nez fin toi !
Je me suis dit : "puisqu'il écrit nomfichier[0] c'est que c'est un tableau statique et qu'il veut montrer qu'il a compris son cours" .... j'ai eu tord !


Message édité par nraynaud le 10-01-2003 à 20:11:19
Reply

Marsh Posté le 10-01-2003 à 20:11:58    

nraynaud a écrit :


 
Evite les nom de variable en majuscules, on les garde pour les macros.
 
Sinon, il sort d'où ton 4 dans fwrite ? à cet endroit on met généralement des sizeof(machin) enfi des trucs mesurés en nombre d'octets


 
le NBELEVES en maj, c'est justement que c'est une constaate en #define .
 
le 4 : c le nombre d'octet d'un flottant sur la machine où je travaille.
 
 
sinon merci pour tes conseils sur gdb

Reply

Marsh Posté le 10-01-2003 à 20:14:41    

mani a écrit :

j'ai un peu de mal avec les fonctions fread et fwrite. Je m'en sers pour enregistrer un tableau de flottants (ici notes) de NBELEVES éléments dans un fichier.
 
Bon le problème c'est que l'execution me rend toujours "segmentation fault" , et je ne vois pas bien d'où ça peut venir. il me semble bien que les paramètres que je passe à fwrite sont correctes, d'après le prototype de cette fonction : size_t   fwrite(const  void  *ptr,  size_t  size,  size_t  nmemb,  FILE *stream);
 
j'ai un autre bout de code similaire avec fread, et j'ai la meme erreur.
je suis sous mandrake 9.0, compilateur gcc.
 
 

Code :
  1. FILE* F;
  2. char *nomFichier;
  3.   printf("Quel est le nom du fichier où vous voulez sauvegarder ?\n" );
  4.   while ( EOF == scanf("%s",&nomFichier[0]) ) 
  5.     printf("veuillez refaire une saisie svp\n" );
  6.  
  7.   F=fopen(nomFichier,"w" );
  8.       if (F==NULL)
  9.          printf("erreur d'ouverture du fichier !\n" );
  10.  
  11.   if (NBELEVES != fwrite(notes,4,NBELEVES,F))
  12.           printf("erreur d'écriture dans le fichier !\n" );

 
 
merci de bien vouloir m'aider


 
bon, Taz a eu le nez creux, scanf ne fait pas l'allocation, don il faut lui passer un pointeur sur un tableau déjà existant qu'il va te remplir :
 
char nomfichier[100];
 
maintenant, il faut brider le scanf pour que l'utilisateur ne puisse pas casser ton programme, mais j'ai la flemme de relire le manuel de scanf.

Reply

Marsh Posté le 10-01-2003 à 20:15:21    

mani a écrit :


 
le NBELEVES en maj, c'est justement que c'est une constaate en #define .
 
le 4 : c le nombre d'octet d'un flottant sur la machine où je travaille.
 
 
sinon merci pour tes conseils sur gdb


 
je parlais du F

Reply

Marsh Posté le 10-01-2003 à 20:15:21   

Reply

Marsh Posté le 10-01-2003 à 20:16:58    

si tu peux t'en passer préfère
 
const int nombre=20;
 
au traditionnel et problématique
 
#define NOMBRE 20
 
 
 
 
il m'est arrivé de tourner en rond en essayant de trouver pourquoi le programme d'un ami plantait... j'ai finalement déniché un #define N 8, vu l'emploi intensif de N comme nom de variables dans sont code et dans le code la bibliotheque qu'il utilisait, c'etait un vrai massacre
 
 
bref, en C, on ne devrait pas se servir du #define pour définir des constantes, AMHA

Reply

Marsh Posté le 10-01-2003 à 20:19:48    

tu peux tracer ton programme plus précisément?
 
dans gdb tu tapes 'break nomfichier.c:ligne' et gdb stoppera. ensuite deroule a coup de de 'n' (next) et de 's' (step)
 
ce que je veux savoir c'est si le scanf passe bien
 
edit: &nomFichier[0] == nomfichier


Message édité par Taz le 10-01-2003 à 20:22:48
Reply

Marsh Posté le 10-01-2003 à 20:20:13    

nraynaud a écrit :


 
bon, Taz a eu le nez creux, scanf ne fait pas l'allocation, don il faut lui passer un pointeur sur un tableau déjà existant qu'il va te remplir :
 
char nomfichier[100];
 
maintenant, il faut brider le scanf pour que l'utilisateur ne puisse pas casser ton programme, mais j'ai la flemme de relire le manuel de scanf.


ok j'ai compris : le proclème viendrais que je n'ai pas d'espace reservé pour nomFichier, ce qui ferait donc un ecrasement memoire, ce qui expliquera le segmentation fault .
 
 ....  j'essaye avec un char nomfichier[100] ..
merci

Reply

Marsh Posté le 10-01-2003 à 20:21:46    

++Taz a écrit :


bref, en C, on ne devrait pas se servir du #define pour définir des constantes, AMHA


 
ben ça faut aller le dire à mon prof alors ...

Reply

Marsh Posté le 10-01-2003 à 20:23:07    

++Taz a écrit :

et quand tu peux tracer ton programme plus précisément?
 
dans gdb tu tapes 'break nomfichier.c:ligne' et gdb stoppera. ensuite deroule a coup de de n (next) et de s(step)
 
ce que je veux savoir c'est si le scanf passe bien
 
edit: &nomFichier[0] == nomfichier


 
il a (pendant une courte durée) exposé son programme complet et j'ai pas vu d'affectation à nomfichier.
 
mani> ARRETE D'EDITER TON POST, LA DISCUTION NE VEUT PLUS RIEN DIRE A FORCE !

Reply

Marsh Posté le 10-01-2003 à 20:23:20    

mani a écrit :


 
ben ça faut aller le dire à mon prof alors ...

je peux pas etre partout

Reply

Marsh Posté le 10-01-2003 à 20:27:58    

nraynaud a écrit :


mani> ARRETE D'EDITER TON POST, LA DISCUTION NE VEUT PLUS RIEN DIRE A FORCE !


 
ok ok j'arrete  :ange:

Reply

Marsh Posté le 10-01-2003 à 20:29:01    

bon de toutes façons c'était ça le probleme : ça venait de nomFichier qui n'était pas correctement alloué. reste plus qu'à regler le pbm du scanf.

Reply

Marsh Posté le 10-01-2003 à 20:32:15    

regarde du coté de fgets peut etre, pour eviter les dépassement de capacité

Reply

Marsh Posté le 10-01-2003 à 21:49:39    

++Taz a écrit :

regarde du coté de fgets peut etre, pour eviter les dépassement de capacité


c'est resolu : appel à fgets, puis appel à sscanf.
 
merci à ceux qui ont pris la peine de repondre au topic.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed