C/C++ 使用rapidjson库 操作Json格式文件(创建、插入、解析、修改、删除)

目录

一、前言

1.简介

2.兼容性

3.下载

4.安装

5.官方文档

6.自述

二、封装Json

1. 创建一个 Document 对象

2. "key":"value"

3. { }

4. [ ]

5. [ { }, { } ]

6. [ [ ], [ ] ]

7. { [ ], [ ] }

8. { { }, { } }

9. 将Document转换为字符串输出

10. 写入文件中

三、解析Json

1. 打开文件读取josn数据

2. 使用读取到的json数据初始化Document对象

3. 直接通过键进行解析

4. 解析对象 { }

5. 解析数组 [ ]

6. 解析数组中的对象 [ { } ]

7. 解析数组中的数组 [ [ ] [ ] ]

8. 解析对象中的数组 { [ ], [ ] }

9. 解析对象中的对象 { { } }

10. 解析结果

四、修改Json

1. 读取json数据并初始化Document对象

2. 直接修改值

3. 修改 { } 中的值

4. 修改数组 [ ] 中的值

5. 修改 [ { } ] 中的值

6. 修改 [ [ ] ] 中的值

7. 修改 { [ ] } 中的值

8. 修改 { { } } 中的值

9. 将Document转换为字符串并写入文件

五、删除Json

1. 读取json数据并初始化Document对象

2. 直接删除

3. 删除 { } 中的值

4. 删除数组 [ ] 中的元素

5. 删除 [ ] 中的 { }

6. 删除 [ ] 中的 [ ]

7. 删除 { } 中的 [ ]

8. 删除 { } 中的 { }

9. 将Document转换为字符串并写入文件

六、全部代码汇总

.h文件

.cpp文件

七、总结


一、前言

1.简介

RapidJSON 是一个 C++ 的 JSON 解析器及生成器。它的灵感来自 RapidXml。

  • RapidJSON 小而全。它同时支持 SAX 和 DOM 风格的 API。SAX 解析器只有约 500 行代码。
  • RapidJSON 快。它的性能可与 strlen() 相比。可支持 SSE2/SSE4.2 加速。
  • RapidJSON 独立。它不依赖于 BOOST 等外部库。它甚至不依赖于 STL。
  • RapidJSON 对内存友好。在大部分 32/64 位机器上,每个 JSON 值只占 16 字节(除字符串外)。它预设使用一个快速的内存分配器,令分析器可以紧凑地分配内存。
  • RapidJSON 对 Unicode 友好。它支持 UTF-8、UTF-16、UTF-32 (大端序/小端序),并内部支持这些编码的检测、校验及转码。例如,RapidJSON 可以在分析一个 UTF-8 文件至 DOM 时,把当中的 JSON 字符串转码至 UTF-16。它也支持代理对(surrogate pair)及 "\u0000"(空字符)。

JSON(JavaScript Object Notation)是一个轻量的数据交换格式。RapidJSON 应该完全遵从 RFC7159/ECMA-404,并支持可选的放宽语法。

2.兼容性

RapidJSON 是跨平台的。

3.下载

https://github.com/Tencent/rapidjson/

4.安装

RapidJSON 是只有头文件的 C++ 库。只需把 include/rapidjson 目录复制至系统或项目的 include 目录中。

5.官方文档

RapidJSON: 首页

以上所提到的,均来自rapidjson官方文档!

6.自述

之前我已经学过了QT如何操作json,然后又学过了使用cjson库,那为什么我还会继续学习rapidjson库呢?

原因很简单,QT自带的json库有bug,当json数据大于100mb的时候,QT是处理不了的;之前做项目被QT这个bug坑惨了。

然后cjson也是轻量级别的,所以也是使用不了。

最后不得已,在网上调研,终于找到一个json库是开源的,可以直接将源码添加到的项目中的,而且还是跨平台,最重要的是,它可以处理超过100mb的json数据,这完全符合我的需求,最后简单学习了一下该库后,并在项目中用上了,效果还行,值得推荐。他就是rapidjson,由腾讯开源的一个json库。特别适合需要处理大型JSON数据的C++开发者使用,解决了QT自带JSON库处理大文件的限制问题。

下图是这篇博客所操作的JSON文件:

使用时记得添加头文件:

#include "include/rapidjson/document.h"
#include "include/rapidjson/writer.h"
#include "include/rapidjson/prettywriter.h"
#include "include/rapidjson/stringbuffer.h"

注意:每个 JSON 值都储存为 Value 类,而 Document 类则表示整个 DOM,它存储了一个 DOM 树的根 Value。RapidJSON 的所有公开类型及函数都在 rapidjson 命名空间中。

重要的枚举:

enum Type {                         kNullType = 0,      //!< null   kFalseType = 1,     //!< false  kTrueType = 2,      //!< true   kObjectType = 3,    //!< object kArrayType = 4,     //!< array  kStringType = 5,    //!< string kNumberType = 6     //!< number 
};                                  

一般来说,调用rapidjson库的函数,都需要在最后一个参数中给其指定分配内存,一般使用Document::GetAllocator()函数进行传参即可。

二、封装Json

1. 创建一个 Document 对象

// 创建一个 Document 对象
rapidjson::Document doc;
// 将Document对象设置为一个Object类型
doc.SetObject();

2. "key":"value"

实现效果:

代码实现上述效果:

std::string keyName = "name";                                                        
QString keyValue = "小明";                                                             
bool vip = false;                                                                    // 如果字符串非常量,需要转换为c语言字符串;    name = "小明"                                              
doc.AddMember(rapidjson::Value(keyName.c_str(), doc.GetAllocator()),                 rapidjson::Value(keyValue.toUtf8().constData(), doc.GetAllocator()),   doc.GetAllocator());                                                   
// 如果字符串是常量,可直接传参;  age = 25                                                         
doc.AddMember("age", 25, doc.GetAllocator());                                        
// vip = false                                                                       
doc.AddMember("vip", vip, doc.GetAllocator());                                       
// address = null                                                                    
doc.AddMember("address", rapidjson::Value(rapidjson::kNullType), doc.GetAllocator());

最后一个参数是内存的分配器,通常使用doc.GetAllocator()获取;

3. { }

实现效果:

代码实现上述效果:

// 1.定义一个空的对象 { }                                                                                  
rapidjson::Value interest(rapidjson::kObjectType);  
// 2.往对象中插入数据                                             
interest.AddMember("basketball", rapidjson::Value("篮球", doc.GetAllocator()), doc.GetAllocator());
interest.AddMember("badminton", rapidjson::Value("羽毛球", doc.GetAllocator()), doc.GetAllocator());
// 3.添加到doc中                                                                                       
doc.AddMember("interest", interest, doc.GetAllocator());                                         

如果键或者值是常量,都可以直接使用常量字符串;

interest.AddMember("basketball", "篮球", doc.GetAllocator());

4. [ ]

实现效果:

代码实现上述效果:

// 定义一个空的数组 [ ]
rapidjson::Value color(rapidjson::kArrayType);
color.PushBack("yellow", doc.GetAllocator());
color.PushBack("gray", doc.GetAllocator());
// 添加到doc中
doc.AddMember("color", color, doc.GetAllocator());

如果需要移除最后一个可以使用:color.PopBack();

5. [ { }, { } ]

实现效果:

代码实现上述效果:

// 数组包含对象 [ {}, {} ]                                                                         
QList<QString> gameList = { "马里奥", "魂斗罗", "雪人兄弟" };                                          
QList<double> pricesList = { 55.55, 66.66, 77 };                                             
// 1.定义空数组                                                                                   
rapidjson::Value like(rapidjson::kArrayType);                                                
for (int i = 0; i < gameList.count(); ++i) {                                                 // 2.定义空的对象                                                                              rapidjson::Value gameObj(rapidjson::kObjectType);                                        // 3.往对象中插入数据                                                                            gameObj.AddMember("game",                                                                rapidjson::Value(gameList[i].toUtf8().constData(), doc.GetAllocator()),doc.GetAllocator());                                                   gameObj.AddMember("price", pricesList[i], doc.GetAllocator());                           // 4.添加到数组中                                                                              like.PushBack(gameObj, doc.GetAllocator());                                              
}                                                                                            
// 5.数组添加到doc中                                                                               
doc.AddMember("like", like, doc.GetAllocator());                                             

6. [ [ ], [ ] ]

实现效果:

代码实现上述效果:

// 数组包含数组   [ [], [] ]                                                                                                   
QList<QList<QString>> schoolList = { { "小学", "初中" }, { "高中", "大学" } };                                                   
// 1.定义空数组                                                                                                               
rapidjson::Value education(rapidjson::kArrayType);                                                                       
for (int i = 0; i < schoolList.count(); ++i) {                                                                           // 2.定义空数组                                                                                                           rapidjson::Value tmpArray(rapidjson::kArrayType);                                                                    QList<QString> tmpList = schoolList[i];                                                                              for (int j = 0; j < tmpList.count(); ++j) {                                                                          // 3.往数组中插入数据                                                                                                    tmpArray.PushBack(rapidjson::Value(tmpList.at(j).toUtf8().constData(), doc.GetAllocator()), doc.GetAllocator()); }                                                                                                                    // 4.数组插入到数组中                                                                                                        education.PushBack(tmpArray, doc.GetAllocator());                                                                    
}                                                                                                                        
// 5.数组包含数组 插入到doc中                                                                                                      
doc.AddMember("education", education, doc.GetAllocator());                                                               

7. { [ ], [ ] }

实现效果:

代码实现上述效果:

// 对象包含数组   { [], [] }                                                              
QList<QList<int>> intList = { { 1, 2 }, { 3, 4 } };                                 
// 1.定义空的对象                                                                         
rapidjson::Value number(rapidjson::kObjectType);                                    
for (int i = 0; i < intList.count(); ++i) {                                         QList<int> tmpList = intList[i];                                                // 2.定义空的数组                                                                     rapidjson::Value tmpArr(rapidjson::kArrayType);                                 for (int j = 0; j < tmpList.count(); ++j) {                                     // 3.往数组中插入数据                                                               tmpArr.PushBack(tmpList.at(j), doc.GetAllocator());                         }                                                                               // 4.数组插入到对象中                                                                   QString key = QString("num%1").arg(i+1);    // 插入到对象中,需要指定key,且不能重名             number.AddMember(rapidjson::Value(key.toUtf8().constData(), doc.GetAllocator()),tmpArr, doc.GetAllocator());                                   
}                                                                                   
// 5.对象包含数组 插入到doc中                                                                 
doc.AddMember("number", number, doc.GetAllocator());                                

8. { { }, { } }

实现效果:

代码实现上述效果:

// 对象包含对象   { {}, {} }                                          
// 1.定义空的对象                                                     
rapidjson::Value languages(rapidjson::kObjectType);             // 2.定义空的子对象,并插入数据                                              
rapidjson::Value serialOne(rapidjson::kObjectType);             
serialOne.AddMember("language", "汉语", doc.GetAllocator());      
serialOne.AddMember("grade", 10, doc.GetAllocator());           
rapidjson::Value serialTwo(rapidjson::kObjectType);             
serialTwo.AddMember("language", "英语", doc.GetAllocator());      
serialTwo.AddMember("grade", 4, doc.GetAllocator());            // 3.对象插入到对象中                                                   
languages.AddMember("serialOne", serialOne, doc.GetAllocator());
languages.AddMember("serialTwo", serialTwo, doc.GetAllocator());// 4.对象包含对象 插入到doc中                                             
doc.AddMember("languages", languages, doc.GetAllocator());      

9. 将Document转换为字符串输出

// 将Document转换为字符串输出                                                         
rapidjson::StringBuffer buffer;                                              
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);  // 默认带换行和缩进
writer.SetFormatOptions(rapidjson::kFormatSingleLineArray);     // 格式会紧凑一点点
doc.Accept(writer);                                                          QByteArray jsonArr = buffer.GetString();                                     
qDebug() << QString(jsonArr);

10. 写入文件中

#define JSON_FILE   "test.json"// 写入文件
writeStrToFile1(JSON_FILE, jsonArr);bool Widget::writeStrToFile1(const QString &fileName, const QByteArray &data)
{QFile file(fileName);if (file.open(QIODevice::WriteOnly)) {file.write(data);} else {return false;}file.close();return true;
}

将json字符串写入文件后,得到如下:

三、解析Json

1. 打开文件读取josn数据

// 读取文件中的json数据                             
QString jsonStr = readFileAllStr(JSON_FILE);
qDebug() << jsonStr; QString Widget::readFileAllStr(const QString &fileName)
{QString str = nullptr;QFile file2(fileName);if (file2.open(QIODevice::ReadOnly | QIODevice::Text)) {QTextStream in(&file2);in.setCodec("UTF-8");str = in.readAll();file2.close();}return str;
}                       

2. 使用读取到的json数据初始化Document对象

// 创建一个 Document 对象                                           
rapidjson::Document doc;                                      // 解析 JSON 字符串                                                
if (doc.Parse(jsonStr.toUtf8().constData()).HasParseError()) {qWarning() << "JSON 解析错误!";                               return ;                                                  
}

3. 直接通过键进行解析

// 访问 JSON 数据// name
if (doc.HasMember("name") && doc["name"].IsString()) {QString name = doc["name"].GetString();rapidjson::Value name1(doc["name"], doc.GetAllocator());qDebug() << "name = " << name;      // 输出有带 " "qDebug() << "name1 = " << name1.GetString();    // 输出没有带 " "
}// age
if (doc.HasMember("age") && doc["age"].IsInt()) {int age = doc["age"].GetInt();rapidjson::Value age1(doc["age"], doc.GetAllocator());// 他俩没有区别qDebug() << "age = " << age;qDebug() << "age1 = " << age1.GetInt();
}// vip
if (doc.HasMember("vip") && doc["vip"].IsBool()) {bool vip = doc["vip"].GetBool();rapidjson::Value vip1(doc["vip"], doc.GetAllocator());// 他俩没有区别qDebug() << "vip = " << vip;qDebug() << "vip1 = " << vip1.GetBool();
}// address
if (doc.HasMember("address") && doc["address"].IsNull()) {qDebug() << "address = null";
}

输出如下: 

4. 解析对象 { }

也就是解析下图内容:

解析代码:

// 解析 { }
if (doc.HasMember("interest") && doc["interest"].IsObject()) {// 1.获得对象
//        const rapidjson::Value &interest = doc["interest"].GetObj();rapidjson::Value interest(doc["interest"], doc.GetAllocator());if (interest.IsObject()) {// 2.获得对象内的值if (interest.HasMember("basketball") && interest["basketball"].IsString()) {QString basketball = interest["basketball"].GetString();qDebug() << "basketball = " << basketball;}// 3.另一种方式rapidjson::Value::ConstMemberIterator itr = interest.FindMember("badminton");if (interest.MemberEnd() != itr && interest["badminton"].IsString()) {QString badminton = interest["badminton"].GetString();qDebug() << "badminton = " << badminton;}}
}

也可以通过迭代器方式解析:

rapidjson::Value::ConstMemberIterator itr = doc.FindMember("interest");
if (doc.MemberEnd() != itr) {// 1.获得对象
//        const rapidjson::Value &interest = doc["interest"].GetObj();rapidjson::Value interest(doc["interest"], doc.GetAllocator());if (interest.IsObject()) {// 2.获得对象内的值rapidjson::Value::ConstMemberIterator it = interest.MemberBegin();for (; it != interest.MemberEnd(); ++it) {QString key = it->name.GetString();QString value = it->value.GetString();qDebug() << key << " = " << value;}}
}

5. 解析数组 [ ]

也就是解析下图内容:

解析代码:

// 解析 [ ]
//    if (doc.HasMember("color") && doc["color"].IsArray()) {
rapidjson::Value::ConstMemberIterator itr = doc.FindMember("color");
if (doc.MemberEnd() != itr && doc["color"].IsArray()) {// 1.获得对象
//        const rapidjson::Value &color = doc["color"].GetArray();rapidjson::Value color(doc["color"], doc.GetAllocator());if (color.IsArray()) {// 2.数组可通过直接for遍历获取值for (rapidjson::SizeType i = 0; i < color.Size(); ++i) {QString value = color[i].GetString();qDebug() << "value = " << value;}}
}

6. 解析数组中的对象 [ { } ]

也就是解析下图内容:

解析代码:

// 解析 [ {} ]
// 1.查找doc是否有 like
rapidjson::Value::ConstMemberIterator itlike = doc.FindMember("like");
if (doc.MemberEnd() != itlike && doc["like"].IsArray()) {// 2.获得like数组const rapidjson::Value &like = doc["like"].GetArray();if (like.IsArray()) {// 3.遍历like数组for (rapidjson::SizeType i = 0; i < like.Size(); ++i) {// 4.获得数组内的对象const rapidjson::Value &obj = like[i].GetObj();if (obj.IsObject()) {// 5.获得对象内的值rapidjson::Value::ConstMemberIterator it = obj.MemberBegin();for (; it != obj.MemberEnd(); ++it) {QString key = it->name.GetString();// 6.注意获取值的类型,否则程序会闪退;(所以,一般推荐json的值都使用字符串存储)QString value = it->value.IsString() ? it->value.GetString() : QString::number(it->value.GetDouble());qDebug() << key << " = " << value;}}}}
}

7. 解析数组中的数组 [ [ ] [ ] ]

也就是解析下图内容:

解析代码:

// 解析  [ [] ]
// 1.查找doc是否有 education
rapidjson::Value::ConstMemberIterator iteducation = doc.FindMember("education");
if (doc.MemberEnd() != iteducation && doc["education"].IsArray()) {// 2.获得education数组const rapidjson::Value &education = doc["education"].GetArray();if (education.IsArray()) {// 3.遍历education数组for (rapidjson::SizeType i = 0; i < education.Size(); ++i) {// 4.获得数组内的数组const rapidjson::Value &arr = education[i].GetArray();// 5.遍历数组,获得数组内的元素for (rapidjson::SizeType j = 0; j < arr.Size(); ++j) {QString value = arr[j].GetString();qDebug() << "value = " << value;}}}
}

8. 解析对象中的数组 { [ ], [ ] }

也就是解析下图内容:

解析代码:

// 解析 { [] }
// 1.查找doc是否有 education
rapidjson::Value::ConstMemberIterator itnumber = doc.FindMember("number");
if (doc.MemberEnd() != itnumber && doc["number"].IsObject()) {// 2.获得number对象const rapidjson::Value &number = doc["number"].GetObj();if (number.IsObject()) {// 3.获得对象内的数组rapidjson::Value::ConstMemberIterator itnum1 = number.FindMember("num1");if (number.MemberEnd() != itnum1 && number["num1"].IsArray()) {const rapidjson::Value &num1 = number["num1"].GetArray();if (num1.IsArray()) {// 4.遍历数组获得里面的值for (rapidjson::SizeType i = 0; i < num1.Size(); ++i) {int value = num1[i].GetInt();qDebug() << "value = " << value;}}}rapidjson::Value::ConstMemberIterator itnum2 = number.FindMember("num2");if (number.MemberEnd() != itnum2 && number["num2"].IsArray()) {const rapidjson::Value &num2 = number["num2"].GetArray();for (rapidjson::SizeType i = 0; i < num2.Size(); ++i) {int value = num2[i].GetInt();qDebug() << "value = " << value;}}}
}

9. 解析对象中的对象 { { } }

也就是解析下图内容:

解析代码:

// 解析 { {} }
// 1.查找languages对象
rapidjson::Value::ConstMemberIterator itLanguages = doc.FindMember("languages");
if (doc.MemberEnd() != itLanguages && doc["languages"].IsObject()) {// 2.获得languages对象const rapidjson::Value &languages = doc["languages"].GetObj();// 3.查找serialOne对象rapidjson::Value::ConstMemberIterator itSerialOne = languages.FindMember("serialOne");if (languages.MemberEnd() != itSerialOne && languages["serialOne"].IsObject()) {// 4.获得serialOne对象const rapidjson::Value &serialOne = languages["serialOne"].GetObj();// 5.获得serialOne对象内的值if (serialOne.HasMember("language") && serialOne["language"].IsString()) {QString basketball = serialOne["language"].GetString();qDebug() << "language = " << basketball;}if (serialOne.HasMember("grade") && serialOne["grade"].IsInt()) {int grade = serialOne["grade"].GetInt();qDebug() << "grade = " << grade;}}// 3.查找serialTwo对象rapidjson::Value::ConstMemberIterator itSerialTwo = languages.FindMember("serialTwo");if (languages.MemberEnd() != itSerialTwo && languages["serialTwo"].IsObject()) {// 4.获得serialTwo对象const rapidjson::Value &serialTwo = languages["serialOne"].GetObj();// 5.获得对象内的值rapidjson::Value::ConstMemberIterator it = serialTwo.MemberBegin();for (; it != serialTwo.MemberEnd(); ++it) {QString key = it->name.GetString();// 注意获取值的类型,否则程序会闪退;(所以,一般推荐json的值都使用字符串存储)QString value = it->value.IsString() ? it->value.GetString() : QString::number(it->value.GetInt());qDebug() << key << " = " << value;}}
}

10. 解析结果

四、修改Json

1. 读取json数据并初始化Document对象

// 读取文件中的json数据
QString jsonStr = readFileAllStr(JSON_FILE);
qDebug() << jsonStr;// 创建一个 Document 对象
rapidjson::Document doc;// 解析 JSON 字符串
if (doc.Parse(jsonStr.toStdString().c_str()).HasParseError()) {qWarning() << "JSON 解析错误!";return ;
}

2. 直接修改值

// 1.判断是否存在(注意,如果不存在,直接修改会报错,所以需要判断是否存在)
if (doc.HasMember("name")) {// 2.直接赋值修改即可doc["name"] = "小杨";
}if (doc.HasMember("age")) {doc["age"] = 100;
}if (doc.HasMember("vip")) {doc["vip"] = true;
}if (doc.HasMember("address")) {doc["address"] = "广东省...";
}

修改前:

修改后:

3. 修改 { } 中的值

// 修改 { }
if (doc.HasMember("interest") && doc["interest"].IsObject()) {// 1.获得对象rapidjson::Value interest(doc["interest"], doc.GetAllocator());// 2.修改对象内的值if (interest.HasMember("basketball")) {interest["basketball"] = "姚明";}// 另一种方式rapidjson::Value::ConstMemberIterator itr = interest.FindMember("badminton");if (interest.MemberEnd() != itr) {interest["badminton"] = "林丹";}// 3.修改完后重新赋值doc["interest"] = interest;
}

修改前:

修改后:

4. 修改数组 [ ] 中的值

// 修改 [ ] 内的值
// 1.查找是否存在数组
rapidjson::Value::ConstMemberIterator itColor = doc.FindMember("color");
if (doc.MemberEnd() != itColor) {// 2.获得数组rapidjson::Value color(doc["color"], doc.GetAllocator());// 3.准备修改的数据QStringList colorList = { "red", "blue" };// 4.数组可通过直接for遍历修改,也可以单独一个也给去修改,通过下标for (rapidjson::SizeType i = 0; i < color.Size(); ++i) {color[i].SetString(colorList[i].toUtf8().constData(), doc.GetAllocator());
//            color[i].Set(colorList[i].toUtf8().constData());  // 也可以使用这个}// 5.修改完后重新赋值doc["color"] = color;
}

修改前:

修改后:

5. 修改 [ { } ] 中的值

// 修改 [ {} ] 内的值
// 1.查找是否存在数组
rapidjson::Value::ConstMemberIterator itLike = doc.FindMember("like");
if (doc.MemberEnd() != itLike) {// 2.获得数组rapidjson::Value like(doc["like"], doc.GetAllocator());// 3.准备修改的数据QStringList gameList = { "中国象棋", "围棋", "五子棋" };QList<double> priceList = { 77.7, 88.8 , 99.9 };// 4.数组可通过直接for遍历修改,也可以单独一个也给去修改,通过下标for (rapidjson::SizeType i = 0; i < like.Size(); ++i) {// 5.获得数组内的对象rapidjson::Value obj(like[i], doc.GetAllocator());// 修改字符串相关if (obj.HasMember("game")) {obj["game"].SetString(gameList[i].toUtf8().constData(), doc.GetAllocator());
//                obj["game"].Set(gameList[i].toUtf8().constData(), doc.GetAllocator());}// 修改整形相关rapidjson::Value::ConstMemberIterator itr = obj.FindMember("price");if (obj.MemberEnd() != itr) {obj["price"] = priceList[i];}like[i] = obj;}// 5.修改完后重新赋值doc["like"] = like;
}

修改前:

修改后:

6. 修改 [ [ ] ] 中的值

// 修改 [ [] ] 内的值
// 1.查找是否存在数组
rapidjson::Value::ConstMemberIterator itEducation = doc.FindMember("education");
if (doc.MemberEnd() != itEducation) {// 2.获得数组rapidjson::Value education(doc["education"], doc.GetAllocator());// 可以使用数组方式去修改
//        education[0][0] = "小学六年级";
//        education[0][1] = "初中初三";
//        education[1][0] = "高中高三";
//        education[1][1] = "大学大四";// 3.准备修改的数据QList<QList<QString>> list = { { "小学六年级", "初中初三" }, { "高中高三", "大学大四" } };// 4.数组可通过直接for遍历修改,也可以单独一个也给去修改,通过下标for (rapidjson::SizeType i = 0; i < education.Size(); ++i) {// 5.获得数组内的数组rapidjson::Value arr(education[i], doc.GetAllocator());for (rapidjson::SizeType j = 0; j < arr.Size(); ++j) {// 修改值arr[j].SetString(list[i][j].toUtf8().constData(), doc.GetAllocator());
//                arr[j].Set(list[i][j].toUtf8().constData(), doc.GetAllocator());}// 重新赋值education[i] = arr;}// 6.修改完后重新赋值doc["education"] = education;
}

修改前:

修改后:

7. 修改 { [ ] } 中的值

// 修改 { [] } 内的值
// 1.查找是否存在对象
rapidjson::Value::ConstMemberIterator itNumber = doc.FindMember("number");
if (doc.MemberEnd() != itNumber) {rapidjson::Value number(doc["number"], doc.GetAllocator());// 2.获得对象内的数组rapidjson::Value num1(number["num1"], doc.GetAllocator());for (rapidjson::SizeType i = 0; i < num1.Size(); ++i) {num1[i] = num1[i].GetInt() + 10;}rapidjson::Value num2(number["num2"], doc.GetAllocator());for (rapidjson::SizeType i = 0; i < num2.Size(); ++i) {num2[i] = num2[i].GetInt() + 10;}// 3.重新在赋值回来number["num1"] = num1;number["num2"] = num2;doc["number"] = number;
}

修改前:

修改后:

8. 修改 { { } } 中的值

// 修改 { { } } 内的值
// 1.查找是否存在对象
rapidjson::Value::ConstMemberIterator itLanguages = doc.FindMember("languages");
if (doc.MemberEnd() != itLanguages) {rapidjson::Value languages(doc["languages"], doc.GetAllocator());// 2.获得对象内的对象rapidjson::Value serialOne(languages["serialOne"], doc.GetAllocator());serialOne["language"].SetString("粤语", doc.GetAllocator());serialOne["grade"].SetInt(9);rapidjson::Value serialTwo(languages["serialTwo"], doc.GetAllocator());serialTwo["language"].SetString("白话", doc.GetAllocator());serialTwo["grade"].SetInt(8);// 3.重新在赋值回来languages["serialOne"] = serialOne;languages["serialTwo"] = serialTwo;doc["languages"] = languages;
}

修改前:

修改后:

9. 将Document转换为字符串并写入文件

// 将Document转换为字符串输出
rapidjson::StringBuffer buffer;
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);  // 默认带换行和缩进
writer.SetFormatOptions(rapidjson::kFormatSingleLineArray);       // 格式会紧凑一点点
doc.Accept(writer);QByteArray jsonArr = buffer.GetString();
qDebug() << QString(jsonArr);// 写入文件
writeStrToFile1(JSON_FILE, jsonArr);

五、删除Json

1. 读取json数据并初始化Document对象

// 读取文件中的json数据
QString jsonStr = readFileAllStr(JSON_FILE);
qDebug() << jsonStr;// 创建一个 Document 对象
rapidjson::Document doc;// 解析 JSON 字符串
if (doc.Parse(jsonStr.toStdString().c_str()).HasParseError()) {qWarning() << "JSON 解析错误!";return ;
}

2. 直接删除

// 1.直接删除即可
doc.RemoveMember("name");
doc.RemoveMember("age");
doc.RemoveMember("vip");
doc.RemoveMember("address");

3. 删除 { } 中的值

// 删除 { } 中的值
// 1.查找是否有对象
if (doc.HasMember("interest") && doc["interest"].IsObject()) {// 2.获得对象rapidjson::Value interest(doc["interest"], doc.GetAllocator());// 3.删除对象内的值interest.RemoveMember("badminton");// 4.删除完后重新赋值doc["interest"] = interest;
}

删除前:

删除后:

4. 删除数组 [ ] 中的元素

// 删除 [ ] 内的值
// 1.查找是否存在数组
rapidjson::Value::ConstMemberIterator itColor = doc.FindMember("color");
if (doc.MemberEnd() != itColor) {// 2.获得数组rapidjson::Value color(doc["color"], doc.GetAllocator());// 3.根据下表删除color.Erase(color.Begin() + 1);  // 删除索引1的元素(第二个元素)//doc.RemoveMember("color");  // 删除键为"color"的整个数组//color.Clear();  // 清空数组,结果为"color":[]// 4.修改完后重新赋值doc["color"] = color;
}

删除前:

删除后:

5. 删除 [ ] 中的 { }

// 删除 [ {} ] 内的值
// 1.查找是否存在数组
rapidjson::Value::ConstMemberIterator itLike = doc.FindMember("like");
if (doc.MemberEnd() != itLike) {// 2.获得数组rapidjson::Value like(doc["like"], doc.GetAllocator());// 3.根据下表删除like.Erase(like.Begin() + 1);  // 删除索引1的元素(第二个元素)// 4.修改完后重新赋值doc["like"] = like;
}

删除前:

删除后:

6. 删除 [ ] 中的 [ ]

// 删除 [ [] ] 内的值
// 1.查找是否存在数组
rapidjson::Value::ConstMemberIterator itEducation = doc.FindMember("education");
if (doc.MemberEnd() != itEducation) {// 2.获得数组rapidjson::Value education(doc["education"], doc.GetAllocator());// 3.根据下表删除education.Erase(education.Begin() + 1);  // 删除索引1的元素(第二个元素)// 4.修改完后重新赋值doc["education"] = education;
}

删除前:

删除后:

7. 删除 { } 中的 [ ]

// 删除 { [] } 内的值
// 1.查找是否存在对象
rapidjson::Value::ConstMemberIterator itNumber = doc.FindMember("number");
if (doc.MemberEnd() != itNumber) {rapidjson::Value number(doc["number"], doc.GetAllocator());// 删除对象内的值number.RemoveMember("num2");doc["number"] = number;
}

删除前:

删除后:

8. 删除 { } 中的 { }

// 删除 { { } } 内的值
// 1.查找是否存在对象
rapidjson::Value::ConstMemberIterator itLanguages = doc.FindMember("languages");
if (doc.MemberEnd() != itLanguages) {rapidjson::Value languages(doc["languages"], doc.GetAllocator());// 删除对象内的值languages.RemoveMember("serialOne");doc["languages"] = languages;
}

删除前:

删除后:

9. 将Document转换为字符串并写入文件

// 将Document转换为字符串输出
rapidjson::StringBuffer buffer;
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);  // 默认带换行和缩进
writer.SetFormatOptions(rapidjson::kFormatSingleLineArray);       // 格式会紧凑一点点
doc.Accept(writer);QByteArray jsonArr = buffer.GetString();
qDebug() << QString(jsonArr);// 写入文件
writeStrToFile1(JSON_FILE, jsonArr);

六、全部代码汇总

rapidjson是纯源码的,所以,只需把 include/rapidjson 目录复制到自己的项目路径中即可(注意包含头文件)。

.h文件

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();/// 创建jsonvoid createJson();/// 解析jsonvoid parseJson();/// 修改jsonvoid modifyJson();/// 删除jsonvoid deleteJson();private:/*** @brief writeStrToFile        往空的文件中写入内容* @param fileNmae              文件路径* @param data                  数据* @return*/bool writeStrToFile(const QString &fileNmae, const QByteArray &data);bool writeStrToFile1(const QString &fileName, const QByteArray &data);/*** @brief readFileAllByte       读取文件内的所有内容* @param fileName              文件路径* @return*/QByteArray readFileAllByte(const QString &fileName);QString readFileAllStr(const QString &fileName);private:Ui::Widget *ui;
};
#endif // WIDGET_H

.cpp文件

#include "widget.h"
#include "ui_widget.h"#include "include/rapidjson/document.h"
#include "include/rapidjson/writer.h"
#include "include/rapidjson/prettywriter.h"
#include "include/rapidjson/stringbuffer.h"#include <QDebug>
#include <QFile>#define JSON_FILE   "test.json"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);createJson();parseJson();modifyJson();deleteJson();
}Widget::~Widget()
{delete ui;
}void Widget::createJson()
{// 创建一个 Document 对象rapidjson::Document doc;// 将Document对象设置为一个Object类型doc.SetObject();std::string keyName = "name";QString keyValue = "小明";bool vip = false;// 最后一个参数是内存的分配器,通常使用doc.GetAllocator()获取// 如果字符串非常量,需要转换为c语言字符串;    name = "小明"doc.AddMember(rapidjson::Value(keyName.c_str(), doc.GetAllocator()),rapidjson::Value(keyValue.toUtf8().constData(), doc.GetAllocator()),doc.GetAllocator());// 如果字符串是常量,可直接传参;  age = 25doc.AddMember("age", 25, doc.GetAllocator());// vip = falsedoc.AddMember("vip", vip, doc.GetAllocator());// address = nulldoc.AddMember("address", rapidjson::Value(rapidjson::kNullType), doc.GetAllocator());/*//! Type of JSON valueenum Type {kNullType = 0,      //!< nullkFalseType = 1,     //!< falsekTrueType = 2,      //!< truekObjectType = 3,    //!< objectkArrayType = 4,     //!< arraykStringType = 5,    //!< stringkNumberType = 6     //!< number};*/// 定义一个空的对象 { }rapidjson::Value interest(rapidjson::kObjectType);interest.AddMember("basketball", "篮球", doc.GetAllocator());interest.AddMember("badminton", rapidjson::Value("羽毛球", doc.GetAllocator()), doc.GetAllocator());// 添加到doc中doc.AddMember("interest", interest, doc.GetAllocator());// 定义一个空的数组 [ ]rapidjson::Value color(rapidjson::kArrayType);color.PushBack("yellow", doc.GetAllocator());color.PushBack("gray", doc.GetAllocator());// 添加到doc中doc.AddMember("color", color, doc.GetAllocator());// 数组包含对象 [ {}, {} ]QList<QString> gameList = { "马里奥", "魂斗罗", "雪人兄弟" };QList<double> pricesList = { 55.55, 66.66, 77 };// 1.定义空数组rapidjson::Value like(rapidjson::kArrayType);for (int i = 0; i < gameList.count(); ++i) {// 2.定义空的对象rapidjson::Value gameObj(rapidjson::kObjectType);// 3.往对象中插入数据gameObj.AddMember("game",rapidjson::Value(gameList[i].toUtf8().constData(), doc.GetAllocator()),doc.GetAllocator());gameObj.AddMember("price", pricesList[i], doc.GetAllocator());// 4.添加到数组中like.PushBack(gameObj, doc.GetAllocator());}// 5.数组添加到doc中doc.AddMember("like", like, doc.GetAllocator());// 数组包含数组   [ [], [] ]QList<QList<QString>> schoolList = { { "小学", "初中" }, { "高中", "大学" } };// 1.定义空数组rapidjson::Value education(rapidjson::kArrayType);for (int i = 0; i < schoolList.count(); ++i) {// 2.定义空数组rapidjson::Value tmpArray(rapidjson::kArrayType);QList<QString> tmpList = schoolList[i];for (int j = 0; j < tmpList.count(); ++j) {// 3.往数组中插入数据tmpArray.PushBack(rapidjson::Value(tmpList.at(j).toUtf8().constData(), doc.GetAllocator()), doc.GetAllocator());}// 4.数组插入到数组中education.PushBack(tmpArray, doc.GetAllocator());}// 5.数组包含数组 插入到doc中doc.AddMember("education", education, doc.GetAllocator());// 对象包含数组   { [], [] }QList<QList<int>> intList = { { 1, 2 }, { 3, 4 } };// 1.定义空的对象rapidjson::Value number(rapidjson::kObjectType);for (int i = 0; i < intList.count(); ++i) {QList<int> tmpList = intList[i];// 2.定义空的数组rapidjson::Value tmpArr(rapidjson::kArrayType);for (int j = 0; j < tmpList.count(); ++j) {// 3.往数组中插入数据tmpArr.PushBack(tmpList.at(j), doc.GetAllocator());}// 4.数组插入到对象中QString key = QString("num%1").arg(i+1);    // 插入到对象中,需要指定key,且不能重名number.AddMember(rapidjson::Value(key.toUtf8().constData(), doc.GetAllocator()),tmpArr, doc.GetAllocator());}// 5.对象包含数组 插入到doc中doc.AddMember("number", number, doc.GetAllocator());// 对象包含对象   { {}, {} }// 1.定义空的对象rapidjson::Value languages(rapidjson::kObjectType);// 2.定义空的子对象,并插入数据rapidjson::Value serialOne(rapidjson::kObjectType);serialOne.AddMember("language", "汉语", doc.GetAllocator());serialOne.AddMember("grade", 10, doc.GetAllocator());rapidjson::Value serialTwo(rapidjson::kObjectType);serialTwo.AddMember("language", "英语", doc.GetAllocator());serialTwo.AddMember("grade", 4, doc.GetAllocator());// 3.对象插入到对象中languages.AddMember("serialOne", serialOne, doc.GetAllocator());languages.AddMember("serialTwo", serialTwo, doc.GetAllocator());// 4.对象包含对象 插入到doc中doc.AddMember("languages", languages, doc.GetAllocator());// 将Document转换为字符串输出rapidjson::StringBuffer buffer;rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);  // 默认带换行和缩进writer.SetFormatOptions(rapidjson::kFormatSingleLineArray);       // 格式会紧凑一点点doc.Accept(writer);QByteArray jsonArr = buffer.GetString();qDebug() << QString(jsonArr);// 写入文件writeStrToFile1(JSON_FILE, jsonArr);
}void Widget::parseJson()
{// 读取文件中的json数据QString jsonStr = readFileAllStr(JSON_FILE);qDebug() << jsonStr;// 创建一个 Document 对象rapidjson::Document doc;// 解析 JSON 字符串if (doc.Parse(jsonStr.toUtf8().constData()).HasParseError()) {qWarning() << "JSON 解析错误!";return ;}// 访问 JSON 数据if (doc.HasMember("name") && doc["name"].IsString()) {QString name = doc["name"].GetString();rapidjson::Value name1(doc["name"], doc.GetAllocator());qDebug() << "name = " << name;      // 输出有带 " "qDebug() << "name1 = " << name1.GetString();    // 输出没有带 " "}if (doc.HasMember("age") && doc["age"].IsInt()) {int age = doc["age"].GetInt();rapidjson::Value age1(doc["age"], doc.GetAllocator());// 他俩没有区别qDebug() << "age = " << age;qDebug() << "age1 = " << age1.GetInt();}if (doc.HasMember("vip") && doc["vip"].IsBool()) {bool vip = doc["vip"].GetBool();rapidjson::Value vip1(doc["vip"], doc.GetAllocator());// 他俩没有区别qDebug() << "vip = " << vip;qDebug() << "vip1 = " << vip1.GetBool();}if (doc.HasMember("address") && doc["address"].IsNull()) {qDebug() << "address = null";}// 解析 { }if (doc.HasMember("interest") && doc["interest"].IsObject()) {// 1.获得对象
//        const rapidjson::Value &interest = doc["interest"].GetObj();rapidjson::Value interest(doc["interest"], doc.GetAllocator());if (interest.IsObject()) {// 2.获得对象内的值if (interest.HasMember("basketball") && interest["basketball"].IsString()) {QString basketball = interest["basketball"].GetString();qDebug() << "basketball = " << basketball;}// 3.另一种方式rapidjson::Value::ConstMemberIterator itr = interest.FindMember("badminton");if (interest.MemberEnd() != itr && interest["badminton"].IsString()) {QString badminton = interest["badminton"].GetString();qDebug() << "badminton = " << badminton;}}}//    rapidjson::Value::ConstMemberIterator itr = doc.FindMember("interest");
//    if (doc.MemberEnd() != itr) {
//        // 1.获得对象const rapidjson::Value &interest = doc["interest"].GetObj();
//        rapidjson::Value interest(doc["interest"], doc.GetAllocator());//        if (interest.IsObject()) {
//            // 2.获得对象内的值
//            rapidjson::Value::ConstMemberIterator it = interest.MemberBegin();
//            for (; it != interest.MemberEnd(); ++it) {
//                QString key = it->name.GetString();
//                QString value = it->value.GetString();
//                qDebug() << key << " = " << value;
//            }
//        }
//    }// 解析 [ ]
//    if (doc.HasMember("color") && doc["color"].IsArray()) {rapidjson::Value::ConstMemberIterator itr = doc.FindMember("color");if (doc.MemberEnd() != itr && doc["color"].IsArray()) {// 1.获得对象
//        const rapidjson::Value &color = doc["color"].GetArray();rapidjson::Value color(doc["color"], doc.GetAllocator());if (color.IsArray()) {// 2.数组可通过直接for遍历获取值for (rapidjson::SizeType i = 0; i < color.Size(); ++i) {QString value = color[i].GetString();qDebug() << "value = " << value;}}}// 解析 [ {} ]// 1.查找doc是否有 likerapidjson::Value::ConstMemberIterator itlike = doc.FindMember("like");if (doc.MemberEnd() != itlike && doc["like"].IsArray()) {// 2.获得like数组const rapidjson::Value &like = doc["like"].GetArray();if (like.IsArray()) {// 3.遍历like数组for (rapidjson::SizeType i = 0; i < like.Size(); ++i) {// 4.获得数组内的对象const rapidjson::Value &obj = like[i].GetObj();if (obj.IsObject()) {// 5.获得对象内的值rapidjson::Value::ConstMemberIterator it = obj.MemberBegin();for (; it != obj.MemberEnd(); ++it) {QString key = it->name.GetString();// 6.注意获取值的类型,否则程序会闪退;(所以,一般推荐json的值都使用字符串存储)QString value = it->value.IsString() ? it->value.GetString() : QString::number(it->value.GetDouble());qDebug() << key << " = " << value;}}}}}// 解析  [ [] ]// 1.查找doc是否有 educationrapidjson::Value::ConstMemberIterator iteducation = doc.FindMember("education");if (doc.MemberEnd() != iteducation && doc["education"].IsArray()) {// 2.获得education数组const rapidjson::Value &education = doc["education"].GetArray();if (education.IsArray()) {// 3.遍历education数组for (rapidjson::SizeType i = 0; i < education.Size(); ++i) {// 4.获得数组内的数组const rapidjson::Value &arr = education[i].GetArray();// 5.遍历数组,获得数组内的元素for (rapidjson::SizeType j = 0; j < arr.Size(); ++j) {QString value = arr[j].GetString();qDebug() << "value = " << value;}}}}// 解析 { [] }// 1.查找doc是否有 educationrapidjson::Value::ConstMemberIterator itnumber = doc.FindMember("number");if (doc.MemberEnd() != itnumber && doc["number"].IsObject()) {// 2.获得number对象const rapidjson::Value &number = doc["number"].GetObj();if (number.IsObject()) {// 3.获得对象内的数组rapidjson::Value::ConstMemberIterator itnum1 = number.FindMember("num1");if (number.MemberEnd() != itnum1 && number["num1"].IsArray()) {const rapidjson::Value &num1 = number["num1"].GetArray();if (num1.IsArray()) {// 4.遍历数组获得里面的值for (rapidjson::SizeType i = 0; i < num1.Size(); ++i) {int value = num1[i].GetInt();qDebug() << "value = " << value;}}}rapidjson::Value::ConstMemberIterator itnum2 = number.FindMember("num2");if (number.MemberEnd() != itnum2 && number["num2"].IsArray()) {const rapidjson::Value &num2 = number["num2"].GetArray();for (rapidjson::SizeType i = 0; i < num2.Size(); ++i) {int value = num2[i].GetInt();qDebug() << "value = " << value;}}}}// 解析 { {} }// 1.查找languages对象rapidjson::Value::ConstMemberIterator itLanguages = doc.FindMember("languages");if (doc.MemberEnd() != itLanguages && doc["languages"].IsObject()) {// 2.获得languages对象const rapidjson::Value &languages = doc["languages"].GetObj();// 3.查找serialOne对象rapidjson::Value::ConstMemberIterator itSerialOne = languages.FindMember("serialOne");if (languages.MemberEnd() != itSerialOne && languages["serialOne"].IsObject()) {// 4.获得serialOne对象const rapidjson::Value &serialOne = languages["serialOne"].GetObj();// 5.获得serialOne对象内的值if (serialOne.HasMember("language") && serialOne["language"].IsString()) {QString basketball = serialOne["language"].GetString();qDebug() << "language = " << basketball;}if (serialOne.HasMember("grade") && serialOne["grade"].IsInt()) {int grade = serialOne["grade"].GetInt();qDebug() << "grade = " << grade;}}// 3.查找serialTwo对象rapidjson::Value::ConstMemberIterator itSerialTwo = languages.FindMember("serialTwo");if (languages.MemberEnd() != itSerialTwo && languages["serialTwo"].IsObject()) {// 4.获得serialTwo对象const rapidjson::Value &serialTwo = languages["serialOne"].GetObj();// 5.获得对象内的值rapidjson::Value::ConstMemberIterator it = serialTwo.MemberBegin();for (; it != serialTwo.MemberEnd(); ++it) {QString key = it->name.GetString();// 注意获取值的类型,否则程序会闪退;(所以,一般推荐json的值都使用字符串存储)QString value = it->value.IsString() ? it->value.GetString() : QString::number(it->value.GetInt());qDebug() << key << " = " << value;}}}
}void Widget::modifyJson()
{// 读取文件中的json数据QString jsonStr = readFileAllStr(JSON_FILE);qDebug() << jsonStr;// 创建一个 Document 对象rapidjson::Document doc;// 解析 JSON 字符串if (doc.Parse(jsonStr.toStdString().c_str()).HasParseError()) {qWarning() << "JSON 解析错误!";return ;}// 修改 JSON 数据// 1.判断是否存在(注意,如果不存在,直接修改会报错,所以需要判断是否存在)if (doc.HasMember("name")) {// 2.直接赋值修改即可doc["name"] = "小杨";}if (doc.HasMember("age")) {doc["age"] = 100;}if (doc.HasMember("vip")) {doc["vip"] = true;}if (doc.HasMember("address")) {doc["address"] = "广东省...";}// 修改 { }if (doc.HasMember("interest") && doc["interest"].IsObject()) {// 1.获得对象rapidjson::Value interest(doc["interest"], doc.GetAllocator());// 2.修改对象内的值if (interest.HasMember("basketball")) {interest["basketball"] = "姚明";}// 另一种方式rapidjson::Value::ConstMemberIterator itr = interest.FindMember("badminton");if (interest.MemberEnd() != itr) {interest["badminton"] = "林丹";}// 3.修改完后重新赋值doc["interest"] = interest;}// 修改 [ ] 内的值// 1.查找是否存在数组rapidjson::Value::ConstMemberIterator itColor = doc.FindMember("color");if (doc.MemberEnd() != itColor) {// 2.获得数组rapidjson::Value color(doc["color"], doc.GetAllocator());// 3.准备修改的数据QStringList colorList = { "red", "blue" };// 4.数组可通过直接for遍历修改,也可以单独一个也给去修改,通过下标for (rapidjson::SizeType i = 0; i < color.Size(); ++i) {color[i].SetString(colorList[i].toUtf8().constData(), doc.GetAllocator());
//            color[i].Set(colorList[i].toUtf8().constData());  // 也可以使用这个}// 5.修改完后重新赋值doc["color"] = color;}// 修改 [ {} ] 内的值// 1.查找是否存在数组rapidjson::Value::ConstMemberIterator itLike = doc.FindMember("like");if (doc.MemberEnd() != itLike) {// 2.获得数组rapidjson::Value like(doc["like"], doc.GetAllocator());// 3.准备修改的数据QStringList gameList = { "中国象棋", "围棋", "五子棋" };QList<double> priceList = { 77.7, 88.8 , 99.9 };// 4.数组可通过直接for遍历修改,也可以单独一个也给去修改,通过下标for (rapidjson::SizeType i = 0; i < like.Size(); ++i) {// 5.获得数组内的对象rapidjson::Value obj(like[i], doc.GetAllocator());// 修改字符串相关if (obj.HasMember("game")) {obj["game"].SetString(gameList[i].toUtf8().constData(), doc.GetAllocator());
//                obj["game"].Set(gameList[i].toUtf8().constData(), doc.GetAllocator());}// 修改整形相关rapidjson::Value::ConstMemberIterator itr = obj.FindMember("price");if (obj.MemberEnd() != itr) {obj["price"] = priceList[i];}like[i] = obj;}// 5.修改完后重新赋值doc["like"] = like;}// 修改 [ [] ] 内的值// 1.查找是否存在数组rapidjson::Value::ConstMemberIterator itEducation = doc.FindMember("education");if (doc.MemberEnd() != itEducation) {// 2.获得数组rapidjson::Value education(doc["education"], doc.GetAllocator());// 可以使用数组方式去修改
//        education[0][0] = "小学六年级";
//        education[0][1] = "初中初三";
//        education[1][0] = "高中高三";
//        education[1][1] = "大学大四";// 3.准备修改的数据QList<QList<QString>> list = { { "小学六年级", "初中初三" }, { "高中高三", "大学大四" } };// 4.数组可通过直接for遍历修改,也可以单独一个也给去修改,通过下标for (rapidjson::SizeType i = 0; i < education.Size(); ++i) {// 5.获得数组内的数组rapidjson::Value arr(education[i], doc.GetAllocator());for (rapidjson::SizeType j = 0; j < arr.Size(); ++j) {// 修改值arr[j].SetString(list[i][j].toUtf8().constData(), doc.GetAllocator());
//                arr[j].Set(list[i][j].toUtf8().constData(), doc.GetAllocator());}// 重新赋值education[i] = arr;}// 6.修改完后重新赋值doc["education"] = education;}// 修改 { [] } 内的值// 1.查找是否存在对象rapidjson::Value::ConstMemberIterator itNumber = doc.FindMember("number");if (doc.MemberEnd() != itNumber) {rapidjson::Value number(doc["number"], doc.GetAllocator());// 2.获得对象内的数组rapidjson::Value num1(number["num1"], doc.GetAllocator());for (rapidjson::SizeType i = 0; i < num1.Size(); ++i) {num1[i] = num1[i].GetInt() + 10;}rapidjson::Value num2(number["num2"], doc.GetAllocator());for (rapidjson::SizeType i = 0; i < num2.Size(); ++i) {num2[i] = num2[i].GetInt() + 10;}// 3.重新在赋值回来number["num1"] = num1;number["num2"] = num2;doc["number"] = number;}// 修改 { { } } 内的值// 1.查找是否存在对象rapidjson::Value::ConstMemberIterator itLanguages = doc.FindMember("languages");if (doc.MemberEnd() != itLanguages) {rapidjson::Value languages(doc["languages"], doc.GetAllocator());// 2.获得对象内的对象rapidjson::Value serialOne(languages["serialOne"], doc.GetAllocator());serialOne["language"].SetString("粤语", doc.GetAllocator());serialOne["grade"].SetInt(9);rapidjson::Value serialTwo(languages["serialTwo"], doc.GetAllocator());serialTwo["language"].SetString("白话", doc.GetAllocator());serialTwo["grade"].SetInt(8);// 3.重新在赋值回来languages["serialOne"] = serialOne;languages["serialTwo"] = serialTwo;doc["languages"] = languages;}// 将Document转换为字符串输出rapidjson::StringBuffer buffer;rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);  // 默认带换行和缩进writer.SetFormatOptions(rapidjson::kFormatSingleLineArray);       // 格式会紧凑一点点doc.Accept(writer);QByteArray jsonArr = buffer.GetString();qDebug() << QString(jsonArr);// 写入文件writeStrToFile1(JSON_FILE, jsonArr);
}void Widget::deleteJson()
{// 读取文件中的json数据QString jsonStr = readFileAllStr(JSON_FILE);qDebug() << jsonStr;// 创建一个 Document 对象rapidjson::Document doc;// 解析 JSON 字符串if (doc.Parse(jsonStr.toStdString().c_str()).HasParseError()) {qWarning() << "JSON 解析错误!";return ;}// 删除 JSON 数据// 1.直接删除即可doc.RemoveMember("name");doc.RemoveMember("age");doc.RemoveMember("vip");doc.RemoveMember("address");// 删除 { } 中的值// 1.查找是否有对象if (doc.HasMember("interest") && doc["interest"].IsObject()) {// 2.获得对象rapidjson::Value interest(doc["interest"], doc.GetAllocator());// 3.删除对象内的值interest.RemoveMember("badminton");// 4.删除完后重新赋值doc["interest"] = interest;}// 删除 [ ] 内的值// 1.查找是否存在数组rapidjson::Value::ConstMemberIterator itColor = doc.FindMember("color");if (doc.MemberEnd() != itColor) {// 2.获得数组rapidjson::Value color(doc["color"], doc.GetAllocator());// 3.根据下表删除color.Erase(color.Begin() + 1);  // 删除索引1的元素(第二个元素)//doc.RemoveMember("color");  // 删除键为"color"的整个数组//color.Clear();  // 清空数组,结果为"color":[]// 4.修改完后重新赋值doc["color"] = color;}// 删除 [ {} ] 内的值// 1.查找是否存在数组rapidjson::Value::ConstMemberIterator itLike = doc.FindMember("like");if (doc.MemberEnd() != itLike) {// 2.获得数组rapidjson::Value like(doc["like"], doc.GetAllocator());// 3.根据下表删除like.Erase(like.Begin() + 1);  // 删除索引1的元素(第二个元素)// 4.修改完后重新赋值doc["like"] = like;}// 删除 [ [] ] 内的值// 1.查找是否存在数组rapidjson::Value::ConstMemberIterator itEducation = doc.FindMember("education");if (doc.MemberEnd() != itEducation) {// 2.获得数组rapidjson::Value education(doc["education"], doc.GetAllocator());// 3.根据下表删除education.Erase(education.Begin() + 1);  // 删除索引1的元素(第二个元素)// 4.修改完后重新赋值doc["education"] = education;}// 删除 { [] } 内的值// 1.查找是否存在对象rapidjson::Value::ConstMemberIterator itNumber = doc.FindMember("number");if (doc.MemberEnd() != itNumber) {rapidjson::Value number(doc["number"], doc.GetAllocator());// 删除对象内的值number.RemoveMember("num2");doc["number"] = number;}// 删除 { { } } 内的值// 1.查找是否存在对象rapidjson::Value::ConstMemberIterator itLanguages = doc.FindMember("languages");if (doc.MemberEnd() != itLanguages) {rapidjson::Value languages(doc["languages"], doc.GetAllocator());// 删除对象内的值languages.RemoveMember("serialOne");doc["languages"] = languages;}// 将Document转换为字符串输出rapidjson::StringBuffer buffer;rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);  // 默认带换行和缩进writer.SetFormatOptions(rapidjson::kFormatSingleLineArray);       // 格式会紧凑一点点doc.Accept(writer);QByteArray jsonArr = buffer.GetString();qDebug() << QString(jsonArr);// 写入文件writeStrToFile1(JSON_FILE, jsonArr);
}bool Widget::writeStrToFile(const QString &fileNmae, const QByteArray &data)
{QFile file(fileNmae);if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {qDebug() << "文件打开失败!" << fileNmae;return false;}const int chunkSize = 8192;    // 每次写入文件的大小QTextStream out(&file);int totalSize = data.size();int writtenSize = 0;qDebug() <<"文件大小 = " << (totalSize / 1024.0) << "KB";while (writtenSize < totalSize) {// 计算当前块的起始位置和大小int currentChunkSize = qMin(chunkSize, totalSize - writtenSize);QString chunk = data.mid(writtenSize, currentChunkSize);QByteArray utf8Chunk = chunk.toUtf8();// 写入当前块out << utf8Chunk;writtenSize += currentChunkSize;if (0 == writtenSize % 10) {// 刷新缓冲区out.flush();}}out.flush();file.close();qDebug() << "写入完成!";return true;
}bool Widget::writeStrToFile1(const QString &fileName, const QByteArray &data)
{QFile file(fileName);if (file.open(QIODevice::WriteOnly)) {file.write(data);} else {return false;}file.close();return true;
}QByteArray Widget::readFileAllByte(const QString &fileName)
{QByteArray byteArray = QByteArray();QFile file2(fileName);if (file2.open(QIODevice::ReadOnly | QIODevice::Text)) {qint64 size = file2.size();byteArray.resize(size);byteArray = file2.readAll();file2.close();}return byteArray;
}QString Widget::readFileAllStr(const QString &fileName)
{QString str = nullptr;QFile file2(fileName);if (file2.open(QIODevice::ReadOnly | QIODevice::Text)) {QTextStream in(&file2);in.setCodec("UTF-8");str = in.readAll();file2.close();}return str;
}

七、总结

在做项目中遇到问题,通过网上了解,往某个方向可以解决,然后自己去学习如何处理,问题解决后,将相关知识点记录下来,分享!

最后,此文章只是记录rapidjson库的一部分操作,如需深入学习,还请移步官方文档;

程序员要养好看文档的习惯。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/912459.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/912459.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

免安装一键修复网络诊断 + 权限修复!打印机共享错误工具适配 Win7/10/11

各位打印小能手们&#xff01;你们有没有遇到过共享打印机出问题&#xff0c;搞得自己焦头烂额的情况&#xff1f;比如系统一更新&#xff0c;打印机就连不上&#xff0c;打印任务失败&#xff0c;真的是让人崩溃啊&#xff01;别慌&#xff0c;今天就给大家全面介绍一款打印机…

电脑分屏快捷键5

按window右箭头&#xff1a; 按window左箭头&#xff1a;

nt!CcFlushCache函数分析之nt!CcFindBcb

nt!CcFindBcb函数分析 第一部分&#xff1a; 1: kd> p nt!CcAcquireByteRangeForWrite0x377: 80a13c49 e866e4ffff call nt!CcFindBcb (80a120b4) 1: kd> t nt!CcFindBcb: 80a120b4 55 push ebp 1: kd> kc # 00 nt!CcFindBcb 01 nt!CcAcqu…

矩阵及矩阵快速幂

一.矩阵与模板 【模板】矩阵求和 时间限制&#xff1a;1秒 内存限制&#xff1a;128M 题目描述 给出两个&#x1d45b;行&#x1d45a;列的矩阵&#xff0c;求两个矩阵的和 输入描述 第一行输入两个以空格分隔的整数&#x1d45b;,&#x1d45a;&#xff0c;表示矩…

rk3588获取探维雷达数据

可以在上期部署完 FASTLIO 的工作空间内&#xff0c;继续部署探维雷达的驱动程序。不要问为什么不用 mid360&#xff0c;因为我手上只有探维雷达。 探维雷达的驱动链接&#xff1a;https://github.com/TanwayLab/tanwaylidar_view/blob/main/README.md 下载驱动并编译 因为沿…

HTML简介,初步了解HTML

<html> <body> <h1>我的第一个标题</h1> <p1>我的第一个段落</p1> </body> </html> 什么是HTML HTML是用来描述网页的一种语言。 HTML指的是超文本标记语言。 HTML不是一种编程语言&#xff0c;而是一种标记语言。 标记语…

ARM集群服务器 定义

ARM集群服务器的核心定义可归纳为以下要点&#xff1a; 一、核心定义 ARM集群服务器是将‌多个基于ARM架构的处理器节点‌集成在单一物理机箱内&#xff0c;通过高速网络互联形成的分布式计算系统。每个节点均具备独立的计算单元&#xff08;如CPU、GPU/NPU&#xff09;、内存…

进程和线程的区别?

进程&#xff08;Process&#xff09;和线程&#xff08;Thread&#xff09;是操作系统资源分配和调度的核心概念&#xff0c;它们的区别主要体现在以下几个方面&#xff1a; 1. ​​定义与资源分配​​ ​​进程​​ 是程序的​​一次执行实例​​&#xff0c;拥有独立的地址空…

AR 学习:开启未来学习新视界​

AR 学习&#xff0c;即增强现实学习&#xff0c;是一种创新的学习方式&#xff0c;它巧妙地将增强现实技术融入到教育领域。简单来说&#xff0c;就是利用 AR 技术把虚拟的信息和现实场景完美融合&#xff0c;为学习者打造出一个沉浸式的学习环境。AR 学习打破了传统学习的边界…

C++并发编程-4.unique_lock,共享锁和递归锁

本文介绍C 并发中使用的其他类型的锁&#xff0c;包括unique_lock&#xff0c;shared_lock, 以及recursive_lock等。shared_lock和unique_lock比较常用&#xff0c;而recursive_lock用的不多&#xff0c;或尽可能规避用这种锁。 unique_lock unique_lock和lock_guard基本用法…

stm32 freertos下基于 hal库的模拟I2C驱动实现

一 前言 最近搞了两个项目&#xff0c;调了一版freertos下基于hal库得模拟I2C驱动&#xff0c;非常实用&#xff0c;直接拷贝就能用&#xff0c;这里做下记录&#xff0c;主要用到如下四个文件&#xff1a; delay.cdelay.hi2cc.ci2cc.h 二 代码实现 delay.c #include "…

文心大模型 4.5 系列开源首发:技术深度解析与应用指南

文心大模型 4.5 系列开源首发&#xff1a;技术深度解析与应用指南 2025 年 6 月 30 日&#xff0c;百度正式在国内领先的开源平台 GitCode 发布文心大模型 4.5 系列开源模型。此次开源不仅覆盖了从数亿到数百亿参数的多种规模&#xff0c;还在多模态理解、指令遵循、世界知识记…

智能制造——58页智慧工厂解决方案【附全文阅读】

适应人群为制造业企业管理者、技术人员及规划改造团队。主要内容是以 JetLinks IoT 平台为基础&#xff0c;构建涵盖设备层、网络层、平台层和应用层的智慧工厂体系&#xff0c;通过多种通信协议实现设备互联&#xff0c;利用大数据、AI 等技术实现数据采集与处理、设备全生命周…

DeepSeek16-open-webui Pipelines开发填坑

一、虚拟环境安装 mkdir open_webui_pipelines cd open_webui_pipelines python -m venv py3119_env call py3119_env\Scripts\activate 二、下载服务以及安装依赖 git clone https://github.com/open-webui/pipelines.git cd pipelines pip install -r requirements.txt三、…

兰亭妙微APP 界面设计与软件开发综合服务商

兰亭妙微作为 APP 界面设计公司与软件开发公司&#xff0c;自 2011 年成立以来&#xff0c;由清华团队主导&#xff0c;在软件和互联网 UI/UE 设计开发领域发展 16 年&#xff0c;积累了一定的行业经验。 在 APP 界面设计方面&#xff0c;我们的团队包含交互设计师、用户体验相…

【算法】动态规划:1137. 第 N 个泰波那契数

1137. 第 N 个泰波那契数 简单 相关标签 premium lock icon 相关企业 提示 泰波那契序列 Tn 定义如下&#xff1a; T0 0, T1 1, T2 1, 且在 n > 0 的条件下 Tn3 Tn Tn1 Tn2 给你整数 n&#xff0c;请返回第 n 个泰波那契数 Tn 的值。 示例 1&#xff1a; 输入&am…

[附源码+数据库+毕业论文]基于Spring+MyBatis+MySQL+Maven+jsp实现的校园家教兼职信息交流平台管理系统,推荐!

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本校园家教兼职信息交流平台就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的…

vue-33(实践练习:使用 Nuxt.js 和 SSR 构建一个简单的博客)

实践练习:使用 Nuxt.js 和 SSR 构建一个简单的博客 使用 Nuxt.js 和 SSR 构建一个简单的博客是巩固你对服务器端渲染理解以及 Nuxt.js 如何简化这一过程的好方法。这个练习将带你完成设置基本博客结构、获取数据并以用户友好的格式展示,同时利用 SSR 的优势来提升 SEO 和性能…

如何在 .Net 7 中使用 MQTT 客户端

介绍 MQTT&#xff08;消息队列遥测传输&#xff09;是一种轻量级消息传递协议&#xff0c;专为资源受限的环境而设计。MQTT 广泛应用于物联网 (IoT) 和机器对机器 (M2M) 通信。 本文将讨论如何在 .NET 7 中实现 MQTT 消费者。我们将使用 MQTTnet 库&#xff0c;这是 C# 中的高…

云上攻防—Docker安全容器逃逸特权模式危险挂载

前言 之前分享的是云服务安全&#xff0c;今天开始云原生安全&#xff0c;安全道路依旧很长。 什么是Docker呢&#xff0c;它是开源的容器化平台&#xff0c;用于开发、部署和运行应用程序。它通过将应用程序及其依赖项打包在轻量级的容器中&#xff0c;实现环境一致性、快速…