做工程时需要使用c++与json文件进行数据交互,且需要处理嵌套数组,选用了rapidjson作为解析器。
rapidjson的API见其官方说明文档:http://rapidjson.org/zh-cn/index.html。
在头文件中新建rapidjson::Document作为全局document,新建vector作为全局vector备用。
rapidjson::Document jsonDocument;
vector< vector<double> > line_v;
一、读取json文件数据于document
void read_json_file(const std::string file_path){
FILE* pFile_r = fopen(file_path.c_str(),"r");
if(pFile_r){
char m_readbuffer[6556];
FileReadStream json_stream(pFile_r,m_readbuffer,sizeof(m_readbuffer));
jsonDocument.ParseStream(json_stream);
fclose(pFile_r);
}
if(!jsonDocument.IsObject()){
jsonDocument.SetObject();
}
}
二、将document数据写入json文件中
void write_json_file(const std::string file_path){
rapidjson::StringBuffer buffer;
rapidjson::Writer< rapidjson::StringBuffer > writer(buffer);
jsonDocument.Accept(writer);
const char* str = buffer.GetString();
FILE * pFile = fopen(file_path.c_str(),"w");
fwrite(str,sizeof(char),strlen(str),pFile);
fclose(pFile);
}
三、读取json文件中名为"VirtualWall"的menber嵌套数组数据数据(格式:[[a1,b1,c1,d1],[a2,b2,c2,d2],...])
void load_json_data(const std::string file_path){
read_json_file(file_path);
if(!jsonDocument.HasMember("VirtualWall")){
rapidjson::Value lineData(rapidjson::kArrayType);
jsonDocument.AddMember("VirtualWall", lineData, jsonDocument.GetAllocator());
write_json_file(file_path);
}
else{
const rapidjson::Value& j_data = jsonDocument["VirtualWall"];
vector<double> line_v_t;
for (rapidjson::SizeType i = 0; i< j_data.Size(); i++){
for(int j = 0; j<4; j++){
line_v_t.push_back(init_data[i][j].GetDouble());
}
line_v.push_back(line_v_t);
line_v_t.clear();
}
}
}
参考数组格式rapidjson::kArrayType的value,使用object形式的value可以解析json中嵌套字典的数据。
四、向json文件中key值为"VirtualWall"的value添加元素[ax,bx,cx,dx]
void add_data(const std::string file_path,vector<double> msg){
read_json_file(json_file_path);
rapidjson::Value l_data_temp(kObjectType);
l_data_temp.SetArray();
vector<double> line_v_t;
for(int i = 0; i < 4; i ++){
l_data_temp.PushBack(msg.data[i],jsonDocument.GetAllocator());
line_v_t.push_back(msg.data[i]);
}
line_v.push_back(line_v_t); //update the vector
jsonDocument["VirtualWall"].PushBack(l_data_temp,jsonDocument.GetAllocator());
write_json_file(json_file_path);
}
五、清空json文件中key值为"VirtualWall"的数据
void clear_data(){
line_v.clear();
read_json_file(json_file_path);
jsonDocument["VirtualWall"].SetArray();
write_json_file(json_file_path);
}
六、删除"VirtualWall"中嵌套数组中的指定元素[ax,bx,cx,dx]
void delete_data(const vector<double> msg){
vector< vector<double> >::iterator it;
vector<double> line_t;
line_t.push_back(msg.data[0]);
line_t.push_back(msg.data[1]);
line_t.push_back(msg.data[2]);
line_t.push_back(msg.data[3]);
for(it = line_v.begin(); it != line_v.end();){
if(data_compare(line_t,*it))
it = line_v.erase(it);
else
++it;
}
read_json_file(json_file_path);
jsonDocument["VirtualWall"].SetArray();
rapidjson::Value l_data_temp(kObjectType);
l_data_temp.SetArray();
for(int i = 0; i < line_v.size(); i++){
for(int j = 0; j < 4; j++){
l_data_temp.PushBack(line_v[i][j],jsonDocument.GetAllocator());
}
jsonDocument["VirtualWall"].PushBack(l_data_temp,jsonDocument.GetAllocator());
l_data_temp.SetArray();
}
write_json_file(json_file_path);
}
bool data_compare(const vector<double> a, const vector<double> b){
int i;
for(i = 0; i < a.size(); i++){
if( a[i] != b[i])
break;
}
if( a.size() == i )
return true;
else
return false;
}