serialization - C++: Writing and Reading objects into a binary file -
i decided read/write file using serialization; however, rights few items. our items dynamically allocated through test scripts after put vector put written script. following code in our main function, switch cases call functions read , write objects, , lastly functions attempt write , read file. not know why it's reading in couple object, great!
//////////////////////////////////////////////////////// // main int main(int argc, char *argv[]) { std::string optioninput; const char *const file_name = "data.dat"; menudisplay(); while (loopbool) { std::cin.clear(); if (selectedobject == select_init) { std::cout << std::endl << "menu (no item): "; } else { std::cout << std::endl << "item " << selectedobject << " menu: "; } try { optioninput = menuinput(); } catch (const input_error &) { std::cout << "input error detected. exiting.\n"; break; } catch (...) { std::cout << "you should not seeing error message.\n"; break; } std::cout << optioninput[0] << std::endl; optionselect(optioninput[0]); } std::cout << "exiting\n" << std::endl; } //////////////////////////////////////////////////////// // case 'w' case 'w': { // writes authors file std::ofstream asavefile("authors.dat"); boost::archive::text_oarchive aarchiveout(asavefile); aarchiveout << authorobject; // writes mediaitem objects file std::ofstream msavefile("items.dat"); boost::archive::text_oarchive marchiveout(msavefile); iomediainfo itemsender; (int mediawrite = 0; mediawrite < mediaobject.size(); mediawrite++) { itemsender.assignvariables(mediaobject[mediawrite]); marchiveout << itemsender; } break; } //////////////////////////////////////////////////////// // case 'z' case 'z': { // reads in authors author array std::ifstream areadfile("authors.dat"); boost::archive::text_iarchive aarchivein(areadfile); aarchivein >> authorobject; // reads in mediaitems std::ifstream mreadfile("items.dat"); boost::archive::text_iarchive marchivein(mreadfile); std::string itemtype; iomediainfo itemreciever; // (int mediaread = 0; mediaread < 20; mediaread++) // { marchivein >> itemreciever; // checks type of current object , creates new mediaitem object in vector store // todo: break case statement repetition functions greater code reuse itemtype = itemreciever.gettype(); switch (itemtype[0]) { case '*': { mediaobject.push_back(new mediainfo()); selectedobject++; mediaobject[selectedobject]->setname(itemreciever.getname()); mediaobject[selectedobject]->setyear(itemreciever.getyear()); mediaobject[selectedobject]->setempty(itemreciever.getempty()); break; } case 'b': { mediaobject.push_back(new bookinfo()); mediaobject[selectedobject]->setname(itemreciever.getname()); mediaobject[selectedobject]->setempty(itemreciever.getempty()); break; } case 'v': { mediaobject.push_back(new videoinfo()); mediaobject[selectedobject]->setname(itemreciever.getname()); mediaobject[selectedobject]->setempty(itemreciever.getempty()); break; } case 'm': { mediaobject.push_back(new musicinfo()); mediaobject[selectedobject]->setname(itemreciever.getname()); mediaobject[selectedobject]->setempty(itemreciever.getempty()); break; } default: { break; } } // } break; } //////////////////////////////////////////////////////// // assignvariable write file void iomediainfo::assignvariables(mediainfo *originalmediaobject) { mediaitemname_ = originalmediaobject->getname(); mediaitemyear_ = originalmediaobject->getyear(); mediaitempagenum_ = originalmediaobject->getpage(); mediaitemprint_ = originalmediaobject->getprint(); mediaitemvalue_ = originalmediaobject->getvalue(); mediaitemtype_ = originalmediaobject->gettype(); isempty_ = originalmediaobject->isempty(); // mediaitemauthor_ = originalmediaobject->getauthor(); } //////////////////////////////////////////////////////// // read file void iomediainfo::printdata() { std::cout << mediaitemname_ << std::endl; }
i think you're mixing paradigms. looks code taken bad c-style sample used fixed length array of manually allocated polymorphic iomediaitem classes (that, add insult injury, contain , serialize manual typeswitch mediainfotype_
).
then you're driving horrendously complicated loop read items , maintain collection invariants (presumably type=='*'
implies isempty()
, vector of mediainfoobjects
contains no invalid objects etc).
boost serialization made do not have worry these things. why use complicated library if you're going clumsy managing , baby steps after all?
just let go. here's taste of like:
#include <iostream> #include <fstream> #include <boost/archive/binary_oarchive.hpp> #include <boost/archive/binary_iarchive.hpp> #include <boost/serialization/serialization.hpp> #include <boost/serialization/vector.hpp> #include <boost/serialization/variant.hpp> #include <boost/serialization/shared_ptr.hpp> #include <boost/make_shared.hpp> namespace media { struct author { std::string name; author(std::string name = "") : name(std::move(name)) {} }; using authorref = boost::shared_ptr<author>; struct commoninfo { std::string name; int year; authorref author; }; struct bookinfo : commoninfo { bookinfo() = default; int pagenum; int print; int value; bookinfo(commoninfo ci, int pagenum, int print, int value) : commoninfo(ci), pagenum(pagenum), print(print), value(value) { } }; struct videoinfo : commoninfo { videoinfo(commoninfo ci = {}) : commoninfo(ci) { } }; struct musicinfo : commoninfo { musicinfo(commoninfo ci = {}) : commoninfo(ci) { } }; using object = boost::variant<bookinfo, musicinfo, videoinfo>; using catalog = std::vector<object>; ////// serialization methods static inline std::ostream& operator<<(std::ostream& os, commoninfo const& ci) { return os << ci.name << " (" << ci.author->name << ")"; } // out-of-class serialization template <typename ar> void serialize(ar& ar, videoinfo& o, unsigned) { ar & boost::serialization::base_object<commoninfo>(o); } template <typename ar> void serialize(ar& ar, musicinfo& o, unsigned) { ar & boost::serialization::base_object<commoninfo>(o); } template <typename ar> void serialize(ar& ar, commoninfo&o, unsigned) { ar & o.name & o.year & o.author; } template <typename ar> void serialize(ar& ar, author& o, unsigned) { ar & o.name; } template <typename ar> void serialize(ar& ar, bookinfo& o, unsigned) { ar & boost::serialization::base_object<commoninfo>(o) & o.pagenum & o.print & o.value ; } } struct library { std::vector<media::authorref> authors; // allow unreferenced authors media::catalog catalog; static library makesample(); static library load(std::string const& fname); void save(std::string const& fname) const; template <typename ar> void serialize(ar&ar,unsigned) { ar & authors & catalog; } }; //////////////////////////////////////////////////////// // main int main() { library::makesample().save("authorsanditems.dat"); auto cloned = library::load("authorsanditems.dat"); (auto& obj : cloned.catalog) std::cout << obj << "\n"; } using namespace media; library library::makesample() { using boost::make_shared; // shared author auto multascripserat = make_shared<author>("scripserat, multa t."); return { { multascripserat, boost::make_shared<author>(author{"sufferer, a."}), // no books/music survived }, { bookinfo { commoninfo { "title 1", 1999, multascripserat }, 453, 7, 3 }, bookinfo { commoninfo { "title 2", 2011, multascripserat }, 200, 5, 1 }, musicinfo { { "pop album", 1972, make_shared<author>("beatles, the") } }, musicinfo { { "title 2", 2011, multascripserat } }, videoinfo { { "the battleship potemkin", 1925, make_shared<author>("eisenstein, sergei") } }, } }; } void library::save(std::string const& fname) const { std::ofstream ofs(fname, std::ios::binary); boost::archive::binary_oarchive oa(ofs); oa << *this; } library library::load(std::string const& fname) { std::ifstream ifs(fname, std::ios::binary); boost::archive::binary_iarchive ia(ifs); library lib; ia >> lib; return lib; }
prints
title 1 (scripserat, multa t.) title 2 (scripserat, multa t.) pop album (beatles, the) title 2 (scripserat, multa t.) battleship potemkin (eisenstein, sergei)
the hexdump of authorsanditems.dat
file:
0000000: 1600 0000 0000 0000 7365 7269 616c 697a ........serializ 0000010: 6174 696f 6e3a 3a61 7263 6869 7665 0b00 ation::archive.. 0000020: 0408 0408 0100 0000 0000 0000 0000 0000 ................ 0000030: 0000 0200 0000 0000 0000 0100 0000 0001 ................ 0000040: 0000 0003 0001 0000 0000 0000 0000 1400 ................ 0000050: 0000 0000 0000 5363 7269 7073 6572 6174 ......scripserat 0000060: 2c20 4d75 6c74 6120 542e 0300 0100 0000 , multa t....... 0000070: 0c00 0000 0000 0000 5375 6666 6572 6572 ........sufferer 0000080: 2c20 412e 0000 0000 0005 0000 0000 0000 , a............. 0000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000a0: 0000 0000 0000 0000 0700 0000 0000 0000 ................ 00000b0: 5469 746c 6520 31cf 0700 0003 0000 0000 title 1......... 00000c0: 00c5 0100 0007 0000 0003 0000 0000 0000 ................ 00000d0: 0007 0000 0000 0000 0054 6974 6c65 2032 .........title 2 00000e0: db07 0000 0300 0000 0000 c800 0000 0500 ................ 00000f0: 0000 0100 0000 0100 0000 0000 0000 0009 ................ 0000100: 0000 0000 0000 0050 6f70 2041 6c62 756d .......pop album 0000110: b407 0000 0300 0200 0000 0c00 0000 0000 ................ 0000120: 0000 4265 6174 6c65 732c 2054 6865 0100 ..beatles, the.. 0000130: 0000 0700 0000 0000 0000 5469 746c 6520 ..........title 0000140: 32db 0700 0003 0000 0000 0002 0000 0000 2............... 0000150: 0000 0000 1700 0000 0000 0000 5468 6520 ............the 0000160: 4261 7474 6c65 7368 6970 2050 6f74 656d battleship potem 0000170: 6b69 6e85 0700 0003 0003 0000 0012 0000 kin............. 0000180: 0000 0000 0045 6973 656e 7374 6569 6e2c .....eisenstein, 0000190: 2053 6572 6765 69 sergei
Comments
Post a Comment