CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[C++] serialiser une map

leolio24
leolio24
Niveau 9
02 juin 2009 à 22:36:38

bonjour!

Voila je bosse sur un projet où j'aurais besoin de sérialiser des données d'un stl::map. C'est un truc que j'ai jamais fait (serialiser une map), et donc est ce que c'est possible? ou alors il faut serialiser toutes les valeurs (avec key correspondantes evidemment) une a une?

si besoin d'autres précisions n'hesitez pas

merci!

leolio24
leolio24
Niveau 9
04 juin 2009 à 16:31:59

pour ceux que ca interesse, voici comment j'ai sérialiser :

void Contig::store (fstream &stream) {
mDirPos::iterator it;

stream.write ((char*)&name, sizeof (string));
stream.write ((char*)&basecalls, sizeof (string));
stream.write ((char*)&quality, sizeof (string));
for (it=directionPosition.begin(); it!=directionPosition.end(); it++) {
stream.write ((char*)&(it->first), sizeof(string));
stream.write ((char*)&(it->second), sizeof(string));
}
}

Sachant qu'a mon avis c'est pas forcement la meilleure/bonne solution vu que sur un autre forum on m'a dit qu'il fallait ecrire directement la pair<key, value>. Mais je sais pas comment faire.

Bref, si quelqu'un a une piste, j'suis preneur. Pareil pour désérialiser tout ca...

Merci!

dnob700
dnob700
Niveau 10
04 juin 2009 à 18:39:02

L'idée serait de surcharger l'opérateur << pour un ofstream (plus générale qu'un fstream) pour l'objet pair<key, value> (ou pour l'itérateur, je ne sais pas trop, je ne connais pas bien la STL), puis d'appeler cette opérateur par la suite. Ce que tu pourrais faire au sein d'une surchage de l'opérateur << pour un ofstream et ton objet Contig.

Est-ce que tu veux juste sérialiser les donnée ? Tu n'auras pas besoin de les relire après ?

leolio24
leolio24
Niveau 9
04 juin 2009 à 19:39:40

Merci deja de ta reponse.

Oui j'ai ensuite besoin de les relire.
Pour les surcharges j'avais fait ceci, sachant que maintenant je sais qu'ils sont obsolètes vu que ma configuration de class Contig a un peu changé, j'ai en effet rajouté la map<string, string> nécessaire.

ostream &operator<< ( ostream &stream, Contig obj ) {
stream << obj.getName() << ':' << obj.getBasecalls() << ':' << obj.getQuality() << ':' << ':' << obj.getQuality() << '\n';
return stream;
}

istream &operator>> (istream &stream, Contig &obj) {
cout << "Name : ";
stream >> obj.name;
cout << "Sequence : ";
stream >> obj.contigBasecalls;
cout << "Quality : ";
stream >> obj.contigQuality;
return stream;
}

Bon je vais me pencher sur comment on surcharge pair<key, value>!
Merci en tout cas deja!

dnob700
dnob700
Niveau 10
04 juin 2009 à 20:35:20

Le problème c'est que pour relire ta map, tu vas relire les éléments un par un et donc il te faut un marqueur de fin de map (sauf si tu n'en stocke qu'une seule par fichier auquel cas c'est gratuit). Car avec la technique que tu utilise (qui est la bonne, à base d'itérateur), tu ne stocke pas le nombre d'éléments.

D'autre part, pour stocker tes chaines, tu utilise des ':' comme délimiteur. Ça peut aller si tu est absolument sûr qu'elles n'en contiendront jamais. Mais il reste le problème que par défaut, ce n'est pas un séparateur pour l'opérateur <<(istream,string), et qu'il va donc falloir parser les chaines lues (en C, on peut changer ce comportement, je ne sais pas si c'est possible en C++).

Ce que tu fais est l'une des choses très fastidieuse à faire en C++. Il y a certainement des bibliothèques qui peuvent t'y aider (regarde du côté de la manipulation de fichiers XML peut-être), mais sinon, c'est l'une des choses qui se fait bien mieux dans des langages plus modernes. (c'est juste une information, pas une incitation à changer de langage).

leolio24
leolio24
Niveau 9
04 juin 2009 à 21:17:10

Merci pour ces infos :)
Pour les map, malheureusement je vais en stocker plusieurs, mais je prend ton idée d'avoir un marqueur de fin de map (nombre d'élément peut être)

Oui il y effectivement des bibliothèque qui aident à sérialiser (boost je crois, mais il y en a d'autre). Mais pour mon projet (et aussi pour ma culture perso), je ne souhaite pas utiliser ces bibliothèques, même si c'est vrai que c'est fastidieux!

Il me semble effectivement qu'en Java c'est plus simple (j'ai jamais testé, mais je crois bien, a verifier donc), mais je ne peux (et veut :p) pas changer de langage, c'est de plus, une contrainte de mon projet.

Bon je vais avancer avec ces infos, si j'ai d'autres questions (ca m'etonnerais pas) je reviendrais.

Merci

leolio24
leolio24
Niveau 9
09 juin 2009 à 15:58:39

Bon voila, j'ai reussi ce que je voulais faire, je post ici ce qui m'a grandement aidé (trouvé sur le net et modifié par moi en guise de test), on sait jamais ca peut peut être aider quelqu'un d'autre. C'est peut etre pas le truc le plus optimisé mais bon ca donnera sans doute une base de départ. Voilou

  1. include <iostream>
  2. include <fstream>
  3. include <vector>
  4. include <string>
  5. include <iterator>

using namespace std;

class Plop {
public :
string name;
string tmp;
pair<string, string> myObj;

Plop () {}

Plop (string i, string s):myObj(i,s), name("ploppy"), tmp("tmp") {}

Plop (const pair<string, string> & obj) : myObj(obj) {}

friend ostream& operator<< (ostream& stream, Plop const &obj) {
stream << obj.name << " " << obj.tmp;
stream << " " <<obj.myObj.first << " " << obj.myObj.second << " ";
return stream;
}

friend istream& operator>> (istream& stream, Plop &obj) {
string n, t, obj1, obj2;
stream >> n;
stream >> t;
stream >> obj1;
stream >> obj2;
return stream;
}

};

int main() {

vector<Plop> v;
vector<string>vv;
string tmp;
char* fileName = "output_file";

Plop p1("11","AA");
Plop p2("22","BB");
Plop p3("33","CC");
Plop p4("44","DD");
Plop p5("55","EE");
Plop p6("66","FF");

v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
v.push_back(p5);
v.push_back(p6);
/*
ofstream ofs(fileName, ios::out | ios::binary);
ostream_iterator<Plop> osi(ofs);
cout << v.size() <<endl;

copy(v.begin(), v.end(), osi);
*/
ifstream ifs(fileName, ios::in | ios::binary);
istream_iterator<string> isi(ifs);

copy(isi, istream_iterator<string>(), back_inserter(vv));
cout << "------" << endl;

cout << vv.size() << endl;

vector<string>::iterator it=vv.begin();
for ( it = vv.begin(); it!= vv.end(); ++it ) {
cout << *it << endl;
}

return 0;
}

Sous forums
  • Aide à l'achat Mac
  • Macintosh
  • Création de Jeux
  • Programmation
  • Création de sites web
  • Linux
  • Internet
  • Steam Deck
  • Hardware
La vidéo du moment