当前位置: 首页 > news >正文

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.lryc.cn/news/578193.html

相关文章:

  • 【2025最新】Ubuntu22.04 安装 MySQL8.0 教程
  • 零成本接入+企业级部署:2025年AI大模型实战指南
  • Linux云计算基础篇(2)
  • 对称非对称加密,https和http,https通讯原理,Charles抓包原理
  • 三态门Multisim电路仿真——硬件工程师笔记
  • 大模型在多发性硬化预测及治疗方案制定中的应用研究
  • Python 安装使用教程
  • 探索未来AI的无限可能:使用oTTomator Live Agent Studio平台上的开源AI代理!
  • JSON-LD 开发手册
  • 衡石科技chatbot分析手册--钉钉数据问答机器人配置
  • 衡石科技使用手册-企业即时通讯工具数据问答机器人用户手册
  • java中agent的作用
  • 免费文件管理 智能转换GC-Prevue:PDF 转 Word 多种格式 一键完成
  • 云手机主要是指什么?
  • 纯前端本地文件管理器(VSCode风格)(浏览器对本地文件增删改查)
  • DAY 45 Tensorboard使用介绍
  • 2 大语言模型基础-2.2 生成式预训练语言模型GPT-2.2.2 有监督下游任务微调-Instruct-GPT强化学习奖励模型的结构改造与维度转换解析
  • 高效读取文件中指定行段的两种方法
  • 矩阵方程 线性代数
  • EA自动交易完全指南:从策略设计到实盘部署
  • 区块链技术有哪些运用场景?
  • CppCon 2018 学习:A Little Order! Delving into the STL sorting algorithms
  • 《如何在 Spring 中实现 MQ 消息的自动重连:监听与发送双通道策略》
  • mkyaffs2img 的 命令行工具的编译
  • Dubbo3高并发控制实战技巧
  • SCAU期末笔记 - 操作系统 选填题
  • QT中QSS样式表的详细介绍
  • localStorage 和 sessionStorage
  • Python + Selenium 自动化爬取途牛动态网页
  • 在vue当中使用动画