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

SL & STL C++ Discussion :

sauvegarder une liste de type <list>


Sujet :

SL & STL C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2009
    Messages : 20
    Par défaut sauvegarder une liste de type <list>
    bonjour,

    si quelqu'un peut me donner un petit coup de pouce sur ce coup-là...

    J'aimerais sauvegarder une liste d'objets (insérés avec la méthode push_back) sur le disque dur à travers un fichier binaire (ou autres?) pour pouvoir la restituer plus tard (au moment d'une autre ouverture du programme).

    petit exemple :

    Code save : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Objet a, b;
    list<Objet*> L;
     
    L.push_back(&a);
    L.push_back(&b);
    // Je sauvegarde ma liste sur dd, comment faire? ofstream?

    Code load : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    list<Objet*>::iterator it;
     
    for(it=L.begin(); ....) { (*it)->fct(); }
    // pour appeler fct de mes objets préalablement sauvegardés
    J'espère avoir été clair, merci d'avance !

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 10
    Par défaut
    list<Objet*> ? C'est pour du polymorphisme ?

    En gros, tu as un objet :

    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
    19
    20
    21
    22
    23
    class Objet
    {
         public :
     
              Objet();
     
              void SetScore(int score);
     
              void SetName(const std::string& name);
     
              int GetScore() const;
     
              const std::string& GetName() const;
     
              // autres méthodes : aucun intérêt ici         
     
             ~Objet();
     
         protected :
     
               int            _score;
               std::string _Name;
    };
    Le but du jeu, c'est de restituer les attributs de l'objet (ici score et name).

    Quand tu vas sauvegarder un objet, tu vas donc avoir ceci (je garantis pas la synthaxe, mais c'est pas l'important) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int score = Objet.GetScore();
    std::string Name = Objet.GetName();
    int name_size = Name.size();
     
    File.write((char*)&score, sizeof(int));
    File.write((char*)&name_size, sizeof(int));
    File.write(Name.c_str(), name_size);
    Et pour récupérer, c'est l'inverse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int score;
    int name_size;
    char* string;
     
    File.load((char*)&score, sizeof(int));
    File.load((char*)&name_size, sizeof(int));
     
    string = new char[name_size];
    File.load(string, name_size);
     
    Objet.SetScore(score);
    Objet.SetName(string);
     
    delete[] string;
    Donc l'idée pour faire un fichier de sauvegarde, c'est de dire : "je vais sauvegarder List.size() Objets." puis de suivre la procédure.

    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
    int list_size = List.size();
    File.write((char*)&list_size, sizeof(int));
     
    int score;
    std::string Name;
    int name_size;
     
    for (std::list<Objet>::const_iterator It = List.begin(); It != List.end(); ++It)
    {
       score = It->GetScore();
       Name = It->GetName();
       name_size = Name.size();
     
       File.write((char*)&score, sizeof(int));
       File.write((char*)&name_size, sizeof(int));
       File.write(Name.c_str(), name_size);
    }
    Et pour lire :

    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
    19
    20
    21
    22
    23
    int list_size;
    File.read((char*)&list_size, sizeof(int));
     
    int score;
    int name_size;
    char* string;
    Objet Objet;
     
    for (int i = 0; i < list_size; ++i)
    {
       File.load((char*)&score, sizeof(int));
       File.load((char*)&name_size, sizeof(int));
     
       string = new char[name_size];
       File.load(string, name_size);
     
       Objet.SetScore(score);
       Objet.SetName(string);
     
       List.push_back(Objet);
     
       delete[] string;
    }
    Voili, voilou. Si tu as des questions...
    Bonne soirée !

  3. #3
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2009
    Messages : 20
    Par défaut
    hé bien je dois dire que ta réponse m'éclaire déjà un petit peu !!

    oui, j'utilise le polymorphisme, l'idée étant de sauvegarder des figures (polygone, cercle...) dans une liste et de la sauvegarder.

    très simplifié çà donnerait :
    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    class Figure { 
               public:
               Figure(Win * _w,int _x,int _y,char *_col):w(_w),x(_x),y(_y),col(_col) { }
               // Win est un objet servant à l'affichage des figures, bref..
               virtual void draw() = 0;
     
               protected:
               Win *w;
               int x, y;   
               char *col;
    };
     
    class Cercle:public Figure {
               public:
               Cercle(Win * _w,int _x,int _y,char *_col):Figure(_w,_x,_y,_col) { }
     
               void draw() {
                      w->dessinerUnCercle(x,y,col);
               }
    };
     
    // ...puis toutes sortes de figures
     
    // pour la liste
    std::list<Figure*> L;
    Win *w;
     
    Cercle c(w,10,10,"#000000");   // par exemple
    L.push_back(&c);
    Rectangle r(.....) // etc..
    tu utilise les fonctions File.write et File.load, s'agit-il d'un ofstream ? si oui, est-il important de l'ouvrir en mode binaire?
    Il me semble avoir déjà testé cette méthode mais sans résultat, je n'arrivais pas à récupérer mes attributs

    merci encore !

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 10
    Par défaut
    Je préfère écrire en binaire. Moins de mauvaises surprises

    Le plus simple est d'écrire le type de ton objet puis, en fonction du type, de le sauvegarder comme il convient.

    Un truc du genre : 0 = carré, 1 = cercle, 2 = rectangle. Une énumération convient parfaitement

    En français, ça donnerait :

    • J'ai 15 objets
    • Pour 15 boucles, je vais :
      • Je regarde le type de mon objet.
      • J'écris dans le fichier le type de mon objet.
      • switch (type_objet) :
        • Si c'est un carré, je fais SauvegarderCarre(std::ofstream&);
        • Si c'est un cercle, je fais SauvegarderCercle(std::ofstream&);
        • etc...


    ps : oui, ça parle bizzarement le français un programme

  5. #5
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  6. #6
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Effectivement, boost::serialisation me parait tout indiqué!
    Ca permettra d'élever un peu l'abstraction de ton programme !

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    on doit pouvoir faire quelque chose avec le polymorphisme non?

    Citation Envoyé par Xahell Voir le message
    Je préfère écrire en binaire. Moins de mauvaises surprises

    Le plus simple est d'écrire le type de ton objet puis, en fonction du type, de le sauvegarder comme il convient.

    Un truc du genre : 0 = carré, 1 = cercle, 2 = rectangle. Une énumération convient parfaitement

    En français, ça donnerait :

    • J'ai 15 objets
    • Pour 15 boucles, je vais :
      • Je regarde le type de mon objet.
      • J'écris dans le fichier le type de mon objet.
      • switch (type_objet) :
        • Si c'est un carré, je fais SauvegarderCarre(std::ofstream&);
        • Si c'est un cercle, je fais SauvegarderCercle(std::ofstream&);
        • etc...


    ps : oui, ça parle bizzarement le français un programme

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par nikko34 Voir le message
    on doit pouvoir faire quelque chose avec le polymorphisme non?
    Non... Il vaut mieux utiliser un visiteur.

  9. #9
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,
    Citation Envoyé par Xahell Voir le message
    Je préfère écrire en binaire. Moins de mauvaises surprises
    De quelles mauvaises surprises veux tu parler

    L'utilisation de fichiers "binaires" présentent un certains nombre d'avantages, qui sont malgré tout contrebalancés par un nombre égal (ou peu s'en faut) d'inconvénient...

    Le principal avantage tient dans le fait qu'une structure de données particulière sera généralement représentée sous la forme d'un nombre de bytes donné, ce qui permet éventuellement un accès indexé et qui évite de passer par la lecture de N données.

    J'admets en outre qu'il y a des cas où l'utilisation de fichiers binaires s'avère indispensable par la nature même des informations à sauvegarder, telles que les images ou les fichier "compressés".

    Mais dés qu'il est question de sauvegarder des données "humainement lisibles", l'utilisation de fichiers texte présente bien souvent des avantages certains, dont le principal est de ne pas être limité à une taille maximale et arbitraire pour la représentation des différents éléments.

    De plus, avec l'avènement du format XML, dont j'admets volontiers qu'il est souvent utilisé un peut trop "à toutes les sauces", nous disposons d'un moyen finalement bien simple pour arriver à assurer une "communicabilité" particulièrement intéressante

    Mais, sans même considérer le format XML, je ne vois pas vraiment ce que tu peux refuser au formax texte
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  10. #10
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Pareil que Koala. J'aurai même plutôt tendance à dire que c'est en mode binaire que l'on peut avoir des surprises, si communique entre plusieurs plateformes qui n'ont pas le même format pour les types de base!
    En mode texte, on aura pas ce problème...

    En ce qui concerne la sérialisation par contre, le mode binaire est vraiment plus rapide (je viens de tester il y a pas très longtemps), et prend beaucoup moins de place...

Discussions similaires

  1. vide une liste de type select
    Par naourass dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 15/04/2009, 09h05
  2. Cocher un items dans une liste de type TCheckListBox
    Par Faith's Fall dans le forum C++Builder
    Réponses: 2
    Dernier message: 02/03/2007, 20h48
  3. [template] Instanciation d'une liste de types pour un plugin
    Par Matthieu Brucher dans le forum C++
    Réponses: 6
    Dernier message: 11/01/2007, 07h54
  4. Comment Manipuler des objets dans une liste de type TList ?
    Par PadawanDuDelphi dans le forum Delphi
    Réponses: 1
    Dernier message: 02/11/2006, 15h40
  5. Réponses: 1
    Dernier message: 24/05/2006, 11h00

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