Probleme de sauvegarde d'une structure dans un fichier binaire

Résolu
issoux Messages postés 58 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 6 mai 2008 - 16 oct. 2005 à 21:57
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 - 17 oct. 2005 à 11:40
Bonsoir, voila j'encode des etudiants + matricule + cotes (tous des champs d'une structure)

les cotes et les matricules sont sauvés correctement dans mon fichier en binaire et lors du chargement je sais les relires ( apres ouverture en lecture du fichier)

Seul les champs "nom" de ma structure ne s'affichent pas, apparemment ils sauvent les adresses de mes champs et non pas leur valeurs. Car au moment du chargement en lecture de mon fichier et que j'essaie d'afficher tous les noms d'etudiants, il m'affiche des symboles ou des données qui se trouve qqpart en mémoire .

Oui car je travail en dynamique , Ma structure est définit comme ceci : struct etu { int mat;
char *nom;
int *tab_cotes;

}

Ne me demander pas (svp) pourquoi je ne travail pas avec des limites statiques pour le champs non c'est la volonté de mon professeur

D'avence merci pour votre aide ....

10 réponses

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
16 oct. 2005 à 23:19
Mais on ne peut pas stocker des pointeurs, quand tu reliras le fichier les adresses pointées seront assurément invalides.
Tu peux écrire le nom comme tu dis sans structure fixe mais faudra un indicateur de longueur devant sinon la relecture du fichier sera hyper longue pour parser la fin des noms, il sera dans tous les cas impossible de relire avec ta structure actuelle.

ciao...
BruNews, MVP VC++
3
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
16 oct. 2005 à 22:10
ben oui c'est clair si tu enregistres des adresses, faudrait qu'ensuite la liste des noms soit rechargée à la même adresse sinon tu obtiens nimporte quoi.

ciao...
BruNews, MVP VC++
0
issoux Messages postés 58 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 6 mai 2008
16 oct. 2005 à 22:26
Oui ca je l'ai bien compris mon erreur, mais comment sauver mes données( champs nom de l'étudiant uniquement) et non pas l'emplacement mémoire où ils se trouvent au moment de l'encodage.

Encore merci .
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
16 oct. 2005 à 22:39
faudrait un
char nom[48]; par exemple
au lieu du pointeur

ciao...
BruNews, MVP VC++
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
issoux Messages postés 58 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 6 mai 2008
16 oct. 2005 à 23:09
Oui ca fonctionne directement ainsi mais toutefois, avec un pointeur sur char ce n'est pas possible ???

Pour vraiment attribuer juste ce qu'il faut en octets pour chaque nom

Parce que créer un char nom[25] , pour toto, y'aura 20 octets inutilisés ...

Je voulais au départ, faire un "strlen" de ma chaine et ensuite

-> p->nom=(char*) malloc (lg*sizeof(char));

et sauvé ainsi la valeur pointé par ce champ de structure et non pas son emplacement en mémoire à ce moment là

Désolé si je persiste à vouloir rester dans cette structure -ci mais c'etait au départ mon énoncé, donc j'aimerais pouvoir terminer de cette facon...

Merci en tous cas .
0
cs_stegano Messages postés 16 Date d'inscription mercredi 6 juillet 2005 Statut Membre Dernière intervention 26 juin 2006
16 oct. 2005 à 23:21
tu peu tjr faire un strlen sur un tableau .... strlen(nom)
0
cs_stegano Messages postés 16 Date d'inscription mercredi 6 juillet 2005 Statut Membre Dernière intervention 26 juin 2006
16 oct. 2005 à 23:24
Il faut savoir qu'un tableau est un pointeur permanent &nom[1] = nom+1 (je voulais juste faire une precision à ma réponse précédente
0
issoux Messages postés 58 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 6 mai 2008
17 oct. 2005 à 00:45
Merci beaucoup je suis rassuré

Bonne soirée
0
issoux Messages postés 58 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 6 mai 2008
17 oct. 2005 à 02:40
A fluut j'ai parlé un peu trop vite, apparemment il est impossible de sauver des champs de structure de tye pointeur( dûmoins pas leur valeurs)dans un fichier binaire ?!

Dés que je rend tout statique y'a pas de probleme... Voila mon code
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include 
#include<string.h>
#include<ctype.h>


#define file "c:\\exo_malloc"


struct etu


            { int mat;


              char nom[25];


              int nbcotes;
              int *tab_cotes;


            };



int recherche_etu (void)


{ FILE *f;
  struct etu *p=NULL;
  char *matr=NULL;
  int mat=0;
  int i=0;
  int test=0;
  f=fopen(file,"rb");



  printf("             recherche donn&#233;e d\'un &#233;tudiant \n");
  printf("           ------------------------------------------\n");
  printf(" entrez le matricule de l\'etudiant rechercher \n");fgets(matr,sizeof matr,stdin);
  mat=atoi(matr);



  if (f)


          { while(fread(p,sizeof *p,1,f)>0)


               { if (p->mat==mat) { printf(" Nom : %s a encoder %d\n\n",p->nom,p->nbcotes);
                                    for (i=0;inbcotes;i++)


                                            { printf(" cote n&#176;%d : %d/25\n",i+1,p->tab_cotes[i]);


                                            }



                                    test=1;
                                  }


               getch();
               }


          } // fin while


else
       { printf(" erreur &#224; l\'ouverture du fichier \n");getch();


       }



if (test==0)
                { printf(" Ce matricule n\'existe pas \n");getch();


                }



fclose(f);
free(p);


return 0;


}



int charger_fichier (void)


{
   FILE*f;
   struct etu *p;


   f=fopen(file,"rb");
clrscr();



printf("            Liste des etudiants et leur matricule   \n");
printf("           ---------------------------------------  \n\n");



   if (f)


           { while (fread(p,sizeof (struct etu),1,f)>0)


                 {


                  printf("   matricule ->  psr%d   nom -> %s   \n",p->mat,p->nom);



                 }
                 getch();


           }


    else


          { printf(" erreur &#224; l\'ouverture du fichier \n");
            getch();


          }
fclose(f);


clrscr();
return 0;


}


int save ( struct etu *p)


{ FILE *f;


f=fopen(file,"ab");


if (f)


         { fwrite(p,sizeof (struct etu),1,f);
         }


clrscr();


printf(" etudiant    Matricule  \n\n");
printf("  %s          psr%d      \n",p->nom,p->mat);


getch();



fclose(f);



return 0;


}



int encode (void)


{  struct etu *p;
   FILE *f;
   int i=0;
   char *matri=NULL;
   char *cote=NULL;
   char *nbcote=NULL;
   char c=NULL;
   int tmp=0;


 clrscr();


 f=fopen(file,"ab");


  if(!f)


         { printf(" erreur &#224; l\'ouverture \n");


           getch();
         }


  else


      {
          do


            {   p=(struct etu *) malloc (sizeof(struct etu));



               printf(" Entrez matricule entre 1 et 25 \n");gets(matri);


               p->mat=atoi(matri);



        printf(" Entrez nom de l\'etudiant  :");gets(p->nom);



               printf(" entrez le nombres de cotes que vous voulez encoder : \n");gets(nbcote);


               p->nbcotes=atoi(nbcote);


               p->tab_cotes=(int*) malloc ((atoi(nbcote))*sizeof(int));


         tmp=atoi(nbcote);


        for (i=0;i<tmp;i++)


                         { printf(" cote n&#176;%d -> \n",i+1);gets(cote);


                           (*p).tab_cotes[i]=atoi(cote);


                         }


        getch();


               save(p);


               free(p);


             printf(" Voulez encoder un nouvel etudiant ? \n");c=toupper(getch());



             } // fin while
             while (c=='O');


      } // fin else



fclose(f);


return 0;


}


int main ()


{
clrscr();


 // remove(file);


 //encode();


recherche_etu();



charger_fichier ();


return 0;


}


Tu dis que je dois ecrire la longueur du nom avant le champs "nom ", oui mais le nom dont tu parle serait de quel type ?? pointeur sur char?

Parce que je viens d'essayer ce que tu dis pour mon tableau de cotes
J'ai rajouter un champ nbcotes qui me dis combien de cotes j'ai .

Donc pendant le Fread, je fais une boucle for de 0 à p->nbcotes, et je lis le nombre mais il m'a sauvé les adresses et non pas les valeurs donc ca pointe n'importe où comme tu dis...

Je comprend pas pourquoi le prof nous demanderais de le faire ainsi si cela ne fonctionne pas, au cours, il nous mettais en garde de ne pas sauver les adresses mais bien les valeurs ... .

Je ne comprend plus rien, et je n'ai cours que Jeudi !!!

Un grand merci pour votre aide !!!
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
17 oct. 2005 à 11:40
http://www.cppfrance.com/code.aspx?id=10966
Exemple où j'écris et relis des structures.

Si ton prof dis que tu dois enregistrer des pointeurs alors faut le faire mais il faut bien ensuite que les noms soient enregistrés quelque part et donc faudra t'arranger pour que les pointeurs référencent correctement vers cette liste de noms.

ciao...
BruNews, MVP VC++
0
Rejoignez-nous