Probleme de sauvegarde d'une structure dans un fichier binaire [Résolu]

issoux 58 Messages postés lundi 25 avril 2005Date d'inscription 6 mai 2008 Dernière intervention - 16 oct. 2005 à 21:57 - Dernière réponse : BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention
- 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 ....
Afficher la suite 

Votre réponse

10 réponses

BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention - 16 oct. 2005 à 23:19
+3
Utile
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++
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de BruNews
BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention - 16 oct. 2005 à 22:10
0
Utile
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++
Commenter la réponse de BruNews
issoux 58 Messages postés lundi 25 avril 2005Date d'inscription 6 mai 2008 Dernière intervention - 16 oct. 2005 à 22:26
0
Utile
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 .
Commenter la réponse de issoux
BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention - 16 oct. 2005 à 22:39
0
Utile
faudrait un
char nom[48]; par exemple
au lieu du pointeur

ciao...
BruNews, MVP VC++
Commenter la réponse de BruNews
issoux 58 Messages postés lundi 25 avril 2005Date d'inscription 6 mai 2008 Dernière intervention - 16 oct. 2005 à 23:09
0
Utile
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 .
Commenter la réponse de issoux
cs_stegano 16 Messages postés mercredi 6 juillet 2005Date d'inscription 26 juin 2006 Dernière intervention - 16 oct. 2005 à 23:21
0
Utile
tu peu tjr faire un strlen sur un tableau .... strlen(nom)
Commenter la réponse de cs_stegano
cs_stegano 16 Messages postés mercredi 6 juillet 2005Date d'inscription 26 juin 2006 Dernière intervention - 16 oct. 2005 à 23:24
0
Utile
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
Commenter la réponse de cs_stegano
issoux 58 Messages postés lundi 25 avril 2005Date d'inscription 6 mai 2008 Dernière intervention - 17 oct. 2005 à 00:45
0
Utile
Merci beaucoup je suis rassuré

Bonne soirée
Commenter la réponse de issoux
issoux 58 Messages postés lundi 25 avril 2005Date d'inscription 6 mai 2008 Dernière intervention - 17 oct. 2005 à 02:40
0
Utile
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 !!!
Commenter la réponse de issoux
BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention - 17 oct. 2005 à 11:40
0
Utile
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++
Commenter la réponse de BruNews

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.