c++ - 使用rapidjson c ++保存/加载对象的向量
问题描述
我正在尝试制作一个简单的“人”对象向量,可以将其保存然后从文件加载到对象向量。我做了一个在一些教程中找到的函数,它返回类中的所有内容,但我不知道现在该怎么做,把它放到一个文件中。我应该使用 i/o 流操作符还是什么?现在我有以下代码:
#include <iostream> // person.h
#include <string>
#include <vector>
using namespace std;
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
using namespace rapidjson;
class person {
public:
std::string name;
string surname;
int age;
person();
~person();
person(string, string, int);
template <typename Writer>
void Serialize(Writer& writer) const {
writer.StartObject();
writer.String("name");
writer.String(name.c_str());
writer.String("surname");
writer.String(surname.c_str());
writer.String(("id"));
writer.Uint(age);
writer.EndObject();
}
std::string serialize(){
StringBuffer s;
Writer<StringBuffer> writer(s);
Serialize(writer);
return s.GetString();
}
};
#include "person.h" // person.cpp
person::person() {
}
person::~person() {
}
person::person(string name, string surname, int age) : name(name), surname(surname), age(age) {
}
#include "person.h" // main.cpp
int main() {
vector<person> Save;
person P1("Tak", "Nie", 20);
person P2("Yes", "No", 10);
Save.push_back(P1);
Save.push_back(P2);
cout << P1.serialize();
cout << P2.serialize();
return 0;
}
解决方案
没有向量的意义person
,因为序列化和存储为 JSON 将非常复杂。
相反,您可以在 a 中维护序列化的对象字符串,vector
并将它们作为json
数组存储到 aDocument
中。
您可以使用以下命令将您的人员json 文档存储到本地存储FileWriteStream
:
#include "include/rapidjson/writer.h"
#include "include/rapidjson/stringbuffer.h"
#include "include/rapidjson/document.h"
#include "include/rapidjson/ostreamwrapper.h"
#include "include/rapidjson/filewritestream.h"
#include "include/rapidjson/filereadstream.h"
#include "fstream"
#include "iostream"
#include "sstream"
vector<string> Save; // replace vector<person> with vector<string>
//
person P1("Tak", "Nie", 20);
person P2("Yes", "No", 10);
// more persons
//
Save.push_back(P1.serialize());
Save.push_back(P2.serialize());
// push more persons
//
Document d; // rapidjson Document
d.SetArray(); // to store Array of objects
rapidjson::Document::AllocatorType& allocator = d.GetAllocator();
// iterate over objects vector created above
// and create rapidjson Values for each object
// Then store the object in Document
for (auto it = Save.begin(); it!=Save.end(); it++){
Value n((*it).c_str(), allocator);
d.PushBack(n,allocator);
}
// save rapidjson Document to local storage file name "output.json"
FILE* fp = fopen("output.json", "wb");
char writeBuffer[65536];
FileWriteStream os(fp, writeBuffer, sizeof(writeBuffer));
Writer<FileWriteStream> writer(os);
d.Accept(writer);
fclose(fp);
现在您的所有对象都已序列化,作为元素存储在文档中的数组中。
现在要将对象恢复为 的类数组person
,例如P[]
,我们可以做相反的操作,首先使用FileReadStream
将存储rapidjson
的数组恢复为Document
,然后遍历您的文档并逐个获取对象,使用数据创建新person
类:
// restore saved rapidjson Document from file "output.json"
FILE* fp = fopen("output.json", "rb"); // non-Windows use "r"
char readBuffer[65536];
FileReadStream is(fp, readBuffer, sizeof(readBuffer));
Document d;
d.ParseStream(is);
fclose(fp);
//
assert(d.IsArray());
int size= d.Size();
person* P[size+1]; // Now create an array of class person to restore retrieved objects.
// person object paramets
std::string theName;
std::string theSur;
int theid;
// loop over the Array Document
for (int i = 0; i < d.Size(); i++)
{
Document P1_doc; // new rapidjson Document
P1_doc.Parse(d[i].GetString()); // parse each object from d into new Dcoument P1_doc
assert(P1_doc.IsObject());
// now restore each person object data
if(P1_doc.HasMember("name")){
const rapidjson::Value& name = P1_doc["name"];
theName = name.GetString();
}
if (P1_doc.HasMember("surname")){
const rapidjson::Value& surname = P1_doc["surname"];
theSur = surname.GetString();
}
if (P1_doc.HasMember("id")){
const rapidjson::Value& id = P1_doc["id"];
theid = id.GetInt();
}
// Now restore a person object from retrieved data
P[i] = new person(theName, theSur, theid);
}
return 0;
推荐阅读
- android - Android 选项菜单延迟打开
- sql - 在 HIVE SQL 中,表每天都会刷新。如何检索过去日期的数据?
- html - scroll-snap-type 不起作用,我该如何解决?
- php - 使用 opcache_reset() 时,PHP 文件是否会被 JIT 重新编译?
- go - 如何上传图片或文件作为后端
- python - 创建一个没有轴但带有标题和 y 标签的子图
- asp.net - POST 命令在 SSL (https:) 中缺少 BODY 参数,但在 http 中没有:
- django - 获取modelfield django的本地文件路径
- react-native - 带有 FlatList React Native 的卡片
- python - Python - 遍历每个页面以获取所有记录