IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++Builder Discussion :

Enregistrer une struct


Sujet :

C++Builder

  1. #1
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2003
    Messages
    332
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2003
    Messages : 332
    Par défaut Enregistrer une struct
    Bonjour,

    Quel est le meilleur moyen d'enregistrer le contenu d'un tableau d'une structure ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    struct _stData {
                         bool bSelected;           
                         char cWord[255];         
                         int iSize;            
                         int iColor;          
                         bool bBold;               
                         bool bItalic;             
                         char cFontName[255];      
                         char cPicture[255];       
                         int iZoom;                     
                         unsigned int iObject;    
                         int iObjectColor;              
                         int iObjectX;                  
                         int iObjectY;                  
                     };
     
    _stData *pData[MAX];

    J'ai essayé ceci, mais ca ne marche vraiment pas bien. Parfois les données sont complètement fausses, ou alors le fichier fait planter mon application.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    FILE *pFile;
     pFile = fopen(aFileName.c_str(),"wb");
     for (int i=0; i < MAX; i++)
    {
       fwrite(&pData[i], sizeof(_stData), 1, pFile);
    }
    fclose(pFile);
    Merci
    Fred

  2. #2
    Membre émérite
    Avatar de bandit boy
    Profil pro
    Inscrit en
    Février 2006
    Messages
    916
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 916
    Par défaut
    Salut,
    Une idée serait de passer par un TStringList. Dans chaque ligne, tu mets une variable (expl:"bSelected=false") et après tu utilises la méthode SaveToFile.

    Sinon tu peux utiliser un fichier .ini qui peut sauvegarder différent type de variable: chaine, entier ... cette dernière est simple efficace et assez approprié pour sauver des variable. Tout est décrit ici

  3. #3
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    pData est un tableau de pointeurs.
    Tu passe l'adresse des éléments de ce tableau à fwrite. C'est pas très logique.
    Il serait plus logique de passer les élément du tableaux qui eux sont sensés contenir l'adresse de structure _stData.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fwrite(pData[i], sizeof(_stData), 1, pFile);
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  4. #4
    Membre émérite
    Homme Profil pro
    Consultant ERP
    Inscrit en
    Février 2004
    Messages
    644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant ERP

    Informations forums :
    Inscription : Février 2004
    Messages : 644
    Par défaut
    Effectivement il s'agit d'un problème d'adressage.

    En C et C++, le nom du tableau correspond à l'adresse du premier octet de ce tableau.

  5. #5
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2003
    Messages
    332
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2003
    Messages : 332
    Par défaut
    Bonjour,

    J'ai encore une petite question concernant le AnsiString.
    Pour enregistrer une variable de type AnsiString, je fais ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    TFileStream *FS = new TFileStream(aFileName, fmCreate);
    AnsiString MaChaine = "blablabla";
    int iSize = MaChaine.Lenght();
    FS->Write(MaChaine.c_str(), iSize);
    delete FS;
    Maintenant je dois récupérer ma chaine, comment dois-je procéder ?


    Merci

  6. #6
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    Et bien tu reouvre ton fichier en lecture fmOpenRead par exemple.
    et tu utilise la methode Read du TFileStream.


    PS : Ton premier problème sa fonctionne ?
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  7. #7
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2003
    Messages
    332
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2003
    Messages : 332
    Par défaut
    Bonjour,

    1] Pour mon premier problème, ca faisait toujours pareil. Parfois ca marchait, parfois il me manquait des données. J'ai donc enregistré élément par élément via la fonction TFileStream.

    2] Qu'elle est la meilleure façon de lire un AnsiString avec la fonction Read de TFileStream ?
    Comme ceci ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    TFileStream *FS = new TFileStream(aFileName, fmOPenRead);
    AnsiString MaChaine = "";
    int iSize = 0;
    FS->Read(&iSize, sizeof(int));
    FS->Read(&MaChaine, iSize);
    delete FS;
    Merci

  8. #8
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    Qu'elle est la meilleure façon de lire un AnsiString avec la fonction Read de TFileStream ?
    Comme ceci ?...
    Tu as testé ton bout de code ? il fonctionne ?


    Tu peut faire un truc dans ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
       #define BUFFER_SIZE 256   //Taille du buffer.
    
       char Buffer[BUFFER_SIZE];
       AnsiString st;
       TFileStream *FS = new TFileStream("texte.txt", fmOpenRead);
       int nbcharlu;
       do {
           nbcharlu = FS->Read(Buffer,BUFFER_SIZE);
           if(nbcharlu<BUFFER_SIZE) Buffer[nbcharlu]=0;
           st += String(Buffer);
       } while(nbcharlu==BUFFER_SIZE);
    
       delete FS;
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  9. #9
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2003
    Messages
    332
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2003
    Messages : 332
    Par défaut
    Bonjour,

    J'ai fais comme ceci, pour l'instant ca à l'air de bien fonctionner.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    TFileStream *FS = new TFileStream("texte.txt", fmOpenRead);
    AnsiString aBuffer="";
    int iSize = 0;
    FS->Read(&iSize,sizeof(int));
    aBuffer.SetLength(iSize);
    FS->Read(aBuffer.c_str(),iSize);
    delete FS;

  10. #10
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2003
    Messages
    332
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2003
    Messages : 332
    Par défaut
    ESt-ce que vous penser que ce code est bon ?
    Pour l'instant ca marche bien, mais je ne suis pas sur ......
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int iSize = 0;
    FS->Read(&iSize,sizeof(int));
    aBuffer.SetLength(iSize);
    FS->Read(aBuffer.c_str(),iSize);

  11. #11
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    Ton code suppose que tu est enregistré la taille du fichier au début du fichier. Est-ce exact.

    Pour c_str() je ne sait pas trop.
    Citation Envoyé par Aide BCB
    La méthode c_str est fournie d'abord pour la lecture de la valeur de l'AnsiString. Pour modifier la valeur de la chaîne, utilisez l'opérateur [] ou les méthodes AnsiString comme Insert et Delete.
    PS : Si ton fichier ne contient que des chaines de caractères tu peut aussi utiliser la TStringList. Elle est plus simple d'utilisation en ce cas là.
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  12. #12
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2003
    Messages
    332
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2003
    Messages : 332
    Par défaut
    Bonjour,

    Ton code suppose que tu est enregistré la taille du fichier au début du fichier. Est-ce exact.
    Non, je n'ai pas écrit la taille du fichier

    Mon fichier contient un mélange de AnsiString, Int et Float.
    J'ai essayé ceci, mais ca ne compile pas, c'est pour cela que j'ai mis aBuffer.c_str() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int iSize = 0;
    FS->Read(&iSize,sizeof(int));
    aBuffer.SetLength(iSize);
    FS->Read(aBuffe[0],iSize);

  13. #13
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    J'ai l'impréssion que tu mélange un peu tout.
    A tu regardé un peu l'aide des classes que tu utilises.

    Les AnsiString encapsule des chaînes de caractères et tu veux y mettre un peu de tout.

    Dans ton bout de code tu lit un entier (int) que tu mets dans la variable
    iSize donc ton fichier est supposé contenir un entier au début.
    (Vu son nom, elle à l'air de représenter une taille.)

    Ensuite tu (essais) de lire iSize octets (Moi je croyais que c'etait la taille du fichier c'est pour cela que je t'en parlais)

    Donc si tu as plusieurs type variables mélangées il faut les lire dans le même ordre qu'elle ont été enregistrée. Comme tu l'as fait pour ta variable iSize.
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  14. #14
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2003
    Messages
    332
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2003
    Messages : 332
    Par défaut
    Bonjour,

    En fait le iSize en début de fichier correspond à la taille d'un AnsiString qui suit juste après. Je me suis peut-être mal expliqué, désolé.
    Ce que je voulais savoirc' est comment récupérer un AnsiString dans un fichier binaire.

    Pour écrire dans mon fichier, j'ai fais ceci : pas de problème pour ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    TFileStream *FS = new TFileStream("texte.txt", fmCreate);
    AnsiString aBuffer="Ici quelque chose dans mon AnsiString";
    int iSize = aBuffer.Lenght();
    FS->Write(&iSize, sizeof(int)); //J'écris la taille de mon AnsiString
    FS->Write(aBuffer.c_str(), iSize); //J'écris iSize octets de mon AnsiString
    FS->Write(&MyFLoat, sizeof(float));
    .../... //J'écris divers float et int dans mon fichier
    delete FS;
    Et pour lire je fais ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    TFileStream *FS = new TFileStream("texte.txt", fmOpenRead);
    AnsiString aBuffer=""; 
    int iSize = 0;
    FS->Read(&iSize,sizeof(int)); // Je recupère la taille de mon AnsiString
    aBuffer.SetLength(iSize); //Je change la taille de aBuffer
    FS->Read(aBuffer.c_str(), iSize); // Je lit iSize octets pour mon AnsiString
    FS->Read(&MyFLoat, sizeof(float));
    .../... //Je lis les divers float et int dans mon fichier
    delete FS;
    Ce code marche bien pour l'instant. J'aurais voulu avoir une confirmation que ce code soit correcte, car je ne voudrais pas avoir des surprises plus tard.... a cause de FS->Read(aBuffer.c_str(), iSize); que je ne sais pas si c'est valable ou pas.

    Merci

  15. #15
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    Comme je t'ai dit plus haut :
    Pour c_str() je ne sait pas trop.

    Citation Envoyé par [B
    Aide BCB[/B]]
    La méthode c_str est fournie d'abord pour la lecture de la valeur de l'AnsiString. Pour modifier la valeur de la chaîne, utilisez l'opérateur [] ou les méthodes AnsiString comme Insert et Delete.
    Donc il serait peut-être mieux de passer par un buffer de char.
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  16. #16
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2003
    Messages
    332
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2003
    Messages : 332
    Par défaut
    Bonjour,

    Aurais-tu STP un petit exemple, car je n'arrive pas à récupérer la chaine complète ?

    Je te remercie

Discussions similaires

  1. implementer une struct dans un .c
    Par jamal dans le forum C
    Réponses: 10
    Dernier message: 10/03/2005, 19h52
  2. Pb lecture d'une struct date
    Par smag dans le forum C++
    Réponses: 13
    Dernier message: 03/03/2005, 22h17
  3. mettre les termes d'un string dans une struct
    Par grand's dans le forum SL & STL
    Réponses: 17
    Dernier message: 29/11/2004, 17h43
  4. Enregistrer une vidéo...
    Par Ptibibi dans le forum DirectX
    Réponses: 3
    Dernier message: 09/06/2004, 18h06
  5. enregistrer une image et un identifiant
    Par dosach dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 18/03/2004, 17h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo