我决定使用序列化来读取/写入文件;但是,它仅对一些项目具有权利。我们的项目通过测试脚本进行动态分配,然后将它们全部放入向量中,然后将它们写入脚本中。以下是我们的主要函数中的代码,在切换情况下,我们调用函数来读写对象,最后是我们试图对文件进行读写的函数。我不知道为什么它只读取几个对象,所以任何帮助都会很棒!
////////////////////////////////////////////////////////
// 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 be seeing this 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 to a file
std::ofstream aSaveFile("authors.dat");
boost::archive::text_oarchive aArchiveOut(aSaveFile);
aArchiveOut << authorObject;
// Writes mediaItem objects to a file
std::ofstream mSaveFile("items.dat");
boost::archive::text_oarchive mArchiveOut(mSaveFile);
ioMediaInfo itemSender;
for (int mediaWrite = 0; mediaWrite < mediaObject.size(); mediaWrite++) {
itemSender.assignVariables(mediaObject[mediaWrite]);
mArchiveOut << itemSender;
}
break;
}
////////////////////////////////////////////////////////
// Case 'Z'
case 'Z': {
// Reads in authors to 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;
// for (int mediaRead = 0; mediaRead < 20; mediaRead++)
// {
mArchiveIn >> itemReciever;
// Checks type of current object and creates a new mediaItem object in the vector to store it
// TODO: Break case statement repetition into functions for 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 where we write to 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();
}
////////////////////////////////////////////////////////
// Where we read the file
void ioMediaInfo::printData() { std::cout << mediaItemName_ << std::endl; }
我认为您正在混合范例。这看起来很像是从不良的C样式示例中获取的代码,该示例使用了固定长度的手动分配的多态ioMediaItem类数组(这会增加伤害,包含并序列化手动typeswitch mediaInfoType_
)。
然后,您正在驱动一个极其复杂的循环以读取项目并维护集合不变式(假定type=='*'
隐含isEmpty()
,并且mediaInfoObjects
的向量不包含无效对象,等等)。
Boost序列化已完成,因此您不要不必担心这些事情。如果毕竟要进行所有笨拙的管理和简单步骤,为什么还要使用复杂的库?
放手。这是可能的样子:
[Live On Coliru] >>
#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; // to 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"); for (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; }
打印
Title 1 (Scripserat, Multa T.) Title 2 (Scripserat, Multa T.) Pop Album (Beatles, The) Title 2 (Scripserat, Multa T.) The Battleship Potemkin (Eisenstein, Sergei)
authorsAndItems.dat
文件的十六进制转储:
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