c++ 使用rapidjson对数据序列化和反序列化(vs2109)

news2024/11/24 10:01:38

  RapidJSON是腾讯开源的一个高效的C++ JSON解析器及生成器,它是只有头文件的C++库,综合性能是最好的。

1. 安装

在NuGet中为项目安装tencent.rapidjson

2. 引用头文件

#include <rapidjson/document.h>
#include <rapidjson/memorystream.h>
#include <rapidjson/prettywriter.h>


3. 头文件定义

添加测试json字符串和类型对应数组

// 测试json字符串
const char* strJson = "{\"name\":\"MenAngel\",\"age\":23,\"hobbys\":[\"语文\",\"数学\",\"英语\",54],\"scores\":{\"数学\":\"90.6\",\"英语\":\"100.0\", \"语文\":\"80.0\"}}";

// 数据类型,和 rapidjson的enum Type 相对应
static const char* kTypeNames[] = { "Null", "False", "True", "Object", "Array", "String", "Number" };

 

4.  修改JSON 内容

/// <summary>
///  修改JSON 内容
/// </summary>
void MyRapidJson::alterJson()
{
    rapidjson::Document doc;
    doc.Parse(strJson);
    cout << "修改前: " << strJson <<"\n" << endl;

    // 修改内容

    rapidjson::Value::MemberIterator iter = doc.FindMember("name");
    if (iter != doc.MemberEnd())
        doc["name"] = "张三";

    iter = doc.FindMember("age");
    if (iter != doc.MemberEnd())
    {
        rapidjson::Value& v1 = iter->value;
        v1 = "40";
    }

    // 修改后的内容写入 StringBuffer 中
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    doc.Accept(writer);

    cout <<"修改后: " << buffer.GetString() << "\n" << endl;
}

运行结果:

{"name":"张三","age":"40","hobbys":["语文","数学","英语",54],"scores":{"数学":"90.6","英语":"100.0","语文":"80.0"}}

5. 生成 json 数据

/// <summary>
/// 生成JSON数据
/// </summary>
void MyRapidJson::createJson()
{
    // 1.准备数据
    string name = "王五";
    string gender = "boy";
    int age = 23;
    bool student = true;
    vector<string> hobbys = { "语文","数学","英语" };
    map<string, double> scores = { {"语文",80},{"数学",90},{"英语",100} };

    //2.初始化DOM
    rapidjson::Document doc;
    rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
    doc.SetObject();

    // 添加数据
    /* 字符串添加 */ 
    rapidjson::Value tempValue1;
    tempValue1.SetString(name.c_str(), allocator);
    doc.AddMember("name", tempValue1, allocator);

    rapidjson::Value tempValue2(rapidjson::kStringType);
    tempValue2.SetString(gender.c_str(), allocator);
    doc.AddMember(rapidjson::StringRef("gender"), tempValue2, allocator);

    /* 数字类型添加 */
    doc.AddMember("age", age, allocator);

    /* bool 类型 */
    rapidjson::Value tempValueStu(rapidjson::kTrueType);
    tempValueStu.SetBool(student);
    doc.AddMember(rapidjson::StringRef("student"), tempValueStu, allocator);

    /* Array 添加数据 */
    rapidjson::Value tempValue3(rapidjson::kArrayType);
    for (auto hobby : hobbys)
    {
        rapidjson::Value hobbyValue(rapidjson::kStringType);
        hobbyValue.SetString(hobby.c_str(), allocator);
        tempValue3.PushBack(hobbyValue, allocator);
    }
    doc.AddMember("hobbys", tempValue3, allocator);

	/* Object 添加 */
	rapidjson::Value tempValue4(rapidjson::kObjectType);
	tempValue4.SetObject();
	for (auto score : scores)
	{
		//rapidjson::Value scoreName(rapidjson::kStringType);
		//scoreName.SetString(score.first.c_str(), allocator);
		//tempValue4.AddMember(scoreName, score.second, allocator);

        // 方法二
		rapidjson::Value scoreName(rapidjson::kStringType);
		scoreName.SetString(score.first.c_str(), allocator);

		rapidjson::Value scoreValue(rapidjson::kStringType);
        char charValue[20];
        itoa(score.second, charValue,10);
		scoreValue.SetString(charValue, allocator);
		tempValue4.AddMember(scoreName, scoreValue, allocator);
	}
    doc.AddMember("scores", tempValue4, allocator);

    // 写入 StringBuffer
    rapidjson::StringBuffer strBuffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(strBuffer);
    doc.Accept(writer);

    cout << strBuffer.GetString() << "\n" << endl;

    string outFileName = "C:\\Users\\Administrator\\Desktop\\creatJson.txt";
    ofstream outfile(outFileName, std::ios::trunc);
    outfile << strBuffer.GetString() << endl;
    outfile.flush();
    outfile.close(); 
}

运行结果:

{"name":"王五","gender":"boy","age":23,"student":true,"hobbys":["语文","数学","英语"],"scores":{"数学":"90","英语":"100","语文":"80"}}

6. json 数据解析

/// <summary>
/// 查询json 内容
/// </summary>
void MyRapidJson::searchJson()
{
    rapidjson::Document doc;
    if (doc.Parse(strJson).HasParseError())
    {
        std::cout << "json 解析错误" << std::endl;
        return;
    }

    cout << "doc 的属性成员有 " << doc.MemberCount() << "个!" << endl;

    vector<string> propertyName;
    int i = 0;
    for (rapidjson::Value::MemberIterator iter = doc.MemberBegin(); iter != doc.MemberEnd(); ++iter)
    {
        cout << ++i << "、 " << iter->name.GetString() << "    is " << kTypeNames[iter->value.GetType()] << endl;
        propertyName.push_back(iter->name.GetString());
    }
    cout << endl;

    for (rapidjson::Value::MemberIterator iter = doc.MemberBegin(); iter != doc.MemberEnd(); ++iter)
    {
        if (iter->value.GetType() == rapidjson::kObjectType || iter->value.GetType() == rapidjson::kArrayType)
            cout << iter->name.GetString() << " : " << endl;
        else 
            cout << iter->name.GetString() << " : ";

        DfsDocument(std::move(iter->value));
    }
}

/// <summary>
///  遍历里面的内容
/// </summary>
/// <param name="val"></param>
void MyRapidJson::DfsDocument(rapidjson::Value val)
{
	if (!val.GetType())
		return;

	switch (val.GetType()) {
	case rapidjson::kNumberType:
		cout << val.GetInt() << endl;
		break;
	case rapidjson::kStringType:
		cout << val.GetString() << endl;
		break;
	case rapidjson::kArrayType:
		for (rapidjson::Value::ValueIterator itr = val.GetArray().begin();
			itr != val.GetArray().end(); ++itr) {
			rapidjson::Value a;
			a = *itr;
			DfsDocument(std::move(a));
		}
		break;
	case rapidjson::kObjectType:
		for (rapidjson::Value::MemberIterator itr = val.GetObject().begin();
			itr != val.GetObject().end(); ++itr) {
			cout << itr->name.GetString() << " ";
			rapidjson::Value a;
			a = itr->value;
			DfsDocument(std::move(a));
		}
	default:
		break;
	}
}

运行结果

这里需要注意: 

object 类型json字符串中,“数字类型” 需转为 “字符串”,否则查询时会报错。

7.  rapidjson 的其他使用方法

/// <summary>
/// json 属性
/// </summary>
void MyRapidJson::JsonAttribute()
{
    rapidjson::Document doc;
    if (doc.Parse(strJson).HasParseError())
    {
        std::cout << "json 解析错误" << std::endl;
        return;
    }

    // 成员判断
    if (doc.HasMember("hobbys") && !doc["hobbys"].Empty())
        cout << "doc[\"hobbys\"] is not empty!" << "\n" << endl;
    else
        cout << "doc[\"hobbys\"] 不存在。" << "\n" << endl;

    //7.Array的大小
    if (doc["hobbys"].IsArray())
    {
        cout << "doc[\"hobbys\"].Capacity() =  \"  Array的容量及大小:\" " << doc["hobbys"].Capacity() << " 项" << endl;
        cout << "doc[\"hobbys\"].Size() =  \"  Array的容量及大小:\" " << doc["hobbys"].Size() << " 项" << endl;
    }


    // 字符串长度获取
    cout << doc["name"].GetString()  <<"  字符串长度 :" << doc["name"].GetStringLength() << endl;

    //4.查询某个成员是否存在
    rapidjson::Value::MemberIterator iter = doc.FindMember("scores");
    if (iter != doc.MemberEnd())
    {
        cout << iter->name.GetString() << " : " << endl;
        DfsDocument(std::move(iter->value));
    }
    else
        cout << "Not Finded!" << endl;

    // 相同判断
    if (doc["name"].GetString() == string("MenAngel") &&
        doc["name"] == "MenAngel" && 
        strcmp(doc["name"].GetString(),"MenAngel") == 0)
    {
        cout << "判断为相等" << endl;
    }

}

运行结果:

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

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

相关文章

成都瀚网科技有限公司:抖店精选联盟怎么用?

抖音精选联盟是抖音电商平台提供的一项服务&#xff0c;旨在为商家提供更多的推广机会和销售渠道。然而&#xff0c;很多人对于如何使用抖店精选联盟以及如何开通这项服务不太了解。本文将为您详细介绍抖店精选联盟的使用和激活流程。 第一节&#xff1a;如何使用抖店精选联盟 …

可以动态改变刻度背景色的车速仪表盘

最近做的项目的主页面需要用到一个仪表盘来动态显示车速&#xff0c;同时改变对应的背景色 仪表盘 开始是想着使用echarts&#xff0c;修修改改拿来用&#xff0c;但是人家客户有规定&#xff0c;必须搞个差不多的&#xff0c;那没办法&#xff0c;自 己动手搞个吧 截图如下&am…

【目标检测】——Gold-YOLO为啥能超过YOLOV8

华为 https://arxiv.org/pdf/2309.11331.pdf 文章的出发点&#xff1a;FPN中的信息传输问题 1. 简介 基于全局信息融合的概念&#xff0c;提出了一种新的收集和分发机制&#xff08;GD&#xff09;&#xff0c;用于在YOLO中进行有效的信息交换。通过全局融合多层特征并将全局信…

AIGC玩转卡通化技术实践

FaceChain写真开源项目插播&#xff1a; 最新 FaceChain支持多人合照写真、上百种单人写真风格&#xff0c;项目信息汇总&#xff1a;ModelScope 魔搭社区 。 github开源直达&#xff08;觉得有趣的点个star哈。&#xff09;&#xff1a;https://github.com/modelscope/…

护眼灯显色指数应达多少?眼科医生推荐灯光显色指数多少合适

台灯的显色指数是其非常重要的指标&#xff0c;它可以表示灯光照射到物体身上&#xff0c;物体颜色的真实程度&#xff0c;一般用平均显色指数Ra来表示&#xff0c;Ra值越高&#xff0c;灯光显色能力越强。常见的台灯显色指数最低要求一般是在Ra80以上即可&#xff0c;比较好的…

Spring进阶(AOP的应用)—— 动态代理AOP后controller层的private方法访问失效的问题

前言 动态代理&#xff0c;面向切面编程AOP&#xff08;Aspect Oriented Programming&#xff09;作为spring中的一个重点和难点&#xff0c;需要不断深入理解&#xff0c;并且在项目中学习如何灵活应用。 本篇博客介绍动态代理AOP在实际应用中遇到的private方法访问失效的问…

亚马逊电动玩具UL696的测试报告办理

在亚马逊平台销售的电子产品&#xff0c;要符合指定的标准&#xff0c;如果不合格很容易发生起火&#xff0c;爆炸等危及消费者生命财产的安全&#xff0c;因此很多客户因为缺少UL报告&#xff0c;导致产品被下架&#xff0c;销售权被移除等问题&#xff0c;也少不了同行之间的…

leetCode 63.不同路径II 动态规划 + 空间复杂度优化 一维dp

63. 不同路径 II - 力扣&#xff08;LeetCode&#xff09; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&…

.NET Core nuget 组件的安装、更新、卸载

上面的 NuGet\ 是可以省略的。 更新 Update-Package xxx 卸载 Uninstall-Package xxx Uninstall-Package Newtonsoft.Json

400G QSFP-DD FR4 与 400G QSFP-DD FR8光模块:哪个更适合您的网络需求?

QSFP-DD 光模块随着光通信市场规模的不断增长已成为400G市场中客户需求量最高的产品。其中400G QSFP-DD FR4和400G QSFP-DD FR8光模块都是针对波分中距离传输&#xff08;2km&#xff09;的解决方案&#xff0c;它们之间有什么不同&#xff1f;应该如何选择应用&#xff1f;飞速…

SpringBoot 学习(二)配置

2. SpringBoot 配置 2.1 配置文件类型 配置文件用于修改 SpringBoot 的默认配置。 2.1.1 properties 文件 **properties ** 是属性文件后缀。 文件名&#xff1a;application.properties 只能保存键值对。 基础语法&#xff1a;keyvalue namewhy注入配置类 Component //…

Java基于SpringBoot的民宿管理系统,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 文章目录 开发环境&#xff1a;后端&#xff1a;前端&#xff1a;数据库&#xff1a; 系统架构&#xff1a…

Vue computed计算属性购物车实例

效果演示 对于computed的计算属性可以通过这个购物车例子来了解&#xff0c;笔者最近很是疲累&#xff0c;真的不想过多解释了&#xff0c;还请读者自行看代码研究。 参考代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"U…

数据库管理-第107期 Relocating PDB(20230927)

数据库管理-第107期 Relocating PDB&#xff08;20230927&#xff09; 在我长期的blog生涯&#xff0c;当需要迁移PDB的时候&#xff0c;出现了几种方式&#xff0c;基本上就是在线克隆或者datapump&#xff0c;然而这两种方式都需要一定的停机时间。在数据库版本一致的情况下…

Redis 数据类型底层原理

String 内部编码有三种&#xff1a;int、embstr、raw int&#xff1a;如果一个字符串对象保存的是整数值&#xff0c;并且这个整数值可以用 long类型来表示(不超过 long 的表示范围&#xff0c;如果超过了 long 的表示范围&#xff0c;那么按照存储字符串的编码来存储&#xf…

notepad++配置python2环境

&#xff08;1&#xff09;python2版本下载&#xff1a;Index of /ftp/python/2.7.8/https://www.python.org/ftp/python/2.7.8/ &#xff08;2&#xff09; 配置notepad环境 1.打开Notepad&#xff0c;点击“插件”-“插件管理器”&#xff0c;在“可用”选项卡中&#xff0c…

使用Process Monitor工具探测日志文件是程序哪个模块生成的

目录 1、问题描述 2、使用Process Monitor监测目标文件是哪个模块生成的思路说明 3、操作Process Monitor监测日志文件是哪个模块生成的 4、通过screenctach.dll库的时间戳&#xff0c;找到其pdb文件&#xff0c;然后去查看详细的函数调用堆栈 5、最后 VC常用功能开发汇总…

C++编程入门与提高:学习策略与技巧

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 摘要&#xff1a;C是一门…

淘宝商品sku信息抓取接口api

在电商行业中&#xff0c;SKU是一个经常被使用的术语&#xff0c;但是对于很多人来说&#xff0c;这个词可能还比较陌生。在这篇文章中&#xff0c;我们将详细解释什么是SKU&#xff0c;以及在电商业务中它的作用和意义。 什么是SKU&#xff1f; SKU是“Stock Keeping Unit”…

Ubuntu 20.04编译GPMP2过程记录

前言 GPMP2是董靖博士等人在16-17年提出的结合GTSAM因子图框架与Gaussian Processes完成motion planning的一项工作。前身源于Barfoot教授的课题组提出的STEAM(Simultaneous Trajectory Estimation and Mapping)问题及其相关工作。在提出董靖博士提出GPMP2后&#xff0c;borgl…