我决定使用序列化来读/写文件;但是,它只限制了几件物品。我们的项目是通过测试脚本动态分配的,然后在它们全部放入向量后,它们将被写入脚本。以下是我们的main函数中的代码,我们调用函数来读取和写入对象的开关情况,最后是我们尝试写入和读取文件的函数。我不知道为什么它只能阅读几个对象,所以任何帮助都会很棒!
////////////////////////////////////////////////////////
// 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; }
答案 0 :(得分:0)
我认为你们正在混合范式。这看起来非常类似于使用固定长度数组的手动分配的多态ioMediaItem类的错误C样式示例(为了增加损伤,包含并序列化手动类型切换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
文件的hexdump:
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