我正在尝试读取结构的向量并将其写入文件。迭代每个结构,首先我写下面结构的大小,然后我写结构。我在阅读文件时遇到崩溃。
结构:
struct Book {
string author;
string title;
string isbn;
int copies;
Status status;
};
从文件加载:
void load_books(vector<Book> *books) {
ifstream readFile;
int read_size;
Book temp;
readFile.open(BOOK_DB_FILE.c_str(), ios::in | ios::binary) ;
while(readFile.read(reinterpret_cast<char*> (&read_size), sizeof(read_size))) {
cout << read_size << endl;
if (!readFile.read(reinterpret_cast<char*> (&temp), read_size)) {
cout << "Failed to read library.dat!" << endl;
}
cout << "Attempting to load book..." << endl;
cout << temp.title << ":" << temp.copies << endl;
(*books).push_back(temp);
}
cout << "Loaded books!" << endl;
}
写入档案:
void save_books(vector<Book> *books) {
ofstream writeFile;
int write_size;
writeFile.open(BOOK_DB_FILE.c_str(), ios::out | ios::binary);
for (int ind = 0 ; ind < (*books).size(); ind++) {
Book book = (*books)[ind];
write_size = sizeof(book);
cout << "Writing book with size: " << write_size << endl;
cout << book.copies << " of " << book.title << " by " << book.author << endl;
writeFile.write(reinterpret_cast<char*>(&write_size), sizeof(write_size));
writeFile.write(reinterpret_cast<char*>(books + ind), write_size);
}
}
答案 0 :(得分:1)
一般情况下,我总是建议使用像Boost.Serialization这样的库,但是,我不允许你使用Boost(或其他任何序列化库)。所以我们会看看你当前的方法。
虽然您将二进制对象布局直接转储到磁盘的方法充满了风险(例如,由于平台依赖性,如字节顺序),但我认为对于纯粹的类项目,我们可以忍受这些缺陷。
现在,您的主要问题是您正在将struct Book
内存表示转储到磁盘并重新读取,但您忽略了std::string
字段未处理的事实
在内部,std::string
不是POD ,而是(大致)另一个为实际字符串数据分配单独内存的类(为了便于说明,假设它在其实现中携带char*
指针。您目前没有存储此数据;你只存储std::string
内部指针的值,并在加载时读回它们。那时,这些内部指针指向无处有意义。
为了大致了解您需要做什么,您必须以递归方式显式地和单独地序列化/反序列化Book
类的所有成员。大概是这样的:
author
title
isbn
copies
status
阅读时,以同样的方式加载每个成员。因此,对于每个“基本”类型(在您的情况下,std::string
,int
和Status
),以及“{”组合“序列化器和反序列化器函数”,您需要一个串行器/解串器函数{{ 1}}依次调用基本成员的序列化/反序列化函数。
这也大致是Boost.Serialization在内部所做的,所以我建议你看看它无论如何。祝你好运!