当前位置: 首页 > 编程日记 > 正文

RapidJSON简介及使用

RapidJSON是腾讯开源的一个高效的C++ JSON解析器及生成器,它是只有头文件的C++库。RapidJSON是跨平台的,支持Windows, Linux, Mac OS X及iOS, Android。它的源码在https://github.com/Tencent/rapidjson/,稳定版本为2016年发布的1.1.0版本。

RapidJSON特点:

(1). RapidJSON小而全:它同时支持SAX和DOM风格的API,SAX解析器只有约500行代码。

(2). RapidJSON快:它的性能可与strlen()相比,可支持SSE2/SSE4.2加速,使用模版及内联函数去降低函数调用开销。

(3). RapidJSON独立:它不依赖于BOOST等外部库,它甚至不依赖于STL。

(4). RapidJSON对内存友好:在大部分32/64位机器上,每个JSON值只占16字节(除字符串外),它预设使用一个快速的内存分配器,令分析器可以紧凑地分配内存。

(5). RapidJSON对Unicode友好:它支持UTF-8、UTF-16、UTF-32(大端序/小端序),并内部支持这些编码的检测、校验及转码。例如,RapidJSON可以在分析一个UTF-8文件至DOM (Document Object Model, 文件对象模型)时,把当中的JSON字符串转码至UTF-16。它也支持代理对(surrogate pair)及"\u0000"(空字符)。

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

以上内容摘自:http://rapidjson.org/zh-cn/,关于RapidJSON的更详细介绍可以参考此网页。

以下是测试代码(test_rapidjson.cpp):

#include "funset.hpp"
#include "rapidjson/document.h"
//#include "rapidjson/writer.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
#include <iostream>
#include <fstream>
#include <string>
#include "common.hpp"int test_rapidjson_parse()
{
#ifdef _MSC_VERconst char* file_name = "E:/GitCode/Messy_Test/testdata/json.data";
#elseconst char* file_name = "testdata/json.data";
#endifstd::ifstream in(file_name);if (!in.is_open()) {fprintf(stderr, "fail to read json file: %s\n", file_name);return -1;}std::string json_content((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());in.close();rapidjson::Document dom;if (!dom.Parse(json_content.c_str()).HasParseError()) {if (dom.HasMember("name") && dom["name"].IsString()) {fprintf(stdout, "name: %s\n", dom["name"].GetString());}if (dom.HasMember("address") && dom["address"].IsString()) {fprintf(stdout, "address: %s\n", utf8_to_gbk(dom["address"].GetString()));}if (dom.HasMember("age") && dom["age"].IsInt()) {fprintf(stdout, "age: %d\n", dom["age"].GetInt());}const char* tmp = "xxx";if (!dom.HasMember(tmp)) {fprintf(stdout, "Warning: it has no member: %s\n", tmp);}if (dom.HasMember("value1") && dom["value1"].IsArray()) {const rapidjson::Value& arr = dom["value1"];for (int i = 0; i < arr.Size(); ++i) {const rapidjson::Value& tmp = arr[i];fprintf(stdout, "value1:\ni = %d:", i);for (int j = 0; j < tmp.Size(); ++j) {if (tmp[j].IsInt())fprintf(stdout, "%d, ", tmp[j].GetInt());if (tmp[j].IsFloat())fprintf(stdout, "%.1f, ", tmp[j].GetFloat());}fprintf(stdout, "\n");}}if (dom.HasMember("value2") && dom["value2"].IsArray()) {const rapidjson::Value& arr = dom["value2"];fprintf(stdout, "value2: ");for (int i = 0; i < arr.Size(); ++i) {fprintf(stdout, "%.2f, ", arr[i].GetFloat());}fprintf(stdout, "\n");}if (dom.HasMember("bei_jing") && dom["bei_jing"].IsObject()) {const rapidjson::Value& obj = dom["bei_jing"];if (obj.HasMember("address") && obj["address"].IsString()) {fprintf(stdout, "address: %s\n", utf8_to_gbk(obj["address"].GetString()));}if (obj.HasMember("car") && obj["car"].IsBool()) {fprintf(stdout, "car: %d\n", obj["car"].GetBool());}if (obj.HasMember("cat") && obj["cat"].IsBool()) {fprintf(stdout, "cat: %d\n", obj["cat"].GetBool());}}if (dom.HasMember("shan_dong") && dom["shan_dong"].IsObject()) {const rapidjson::Value& obj = dom["shan_dong"];if (obj.HasMember("address") && obj["address"].IsString()) {fprintf(stdout, "address: %s\n", utf8_to_gbk(obj["address"].GetString()));}if (obj.HasMember("value1") && obj["value1"].IsArray()) {const rapidjson::Value& arr = obj["value1"];if (arr[0].HasMember("ji_nan") && arr[0]["ji_nan"].IsString()) {fprintf(stdout, "ji_nan: %s\n", utf8_to_gbk(arr[0]["ji_nan"].GetString()));}if (arr[0].HasMember("tai_an") && arr[0]["tai_an"].IsString()) {fprintf(stdout, "tai_an: %s\n", utf8_to_gbk(arr[0]["tai_an"].GetString()));}}}} else {fprintf(stderr, "fail to parse json file: %s\n", file_name);return -1;}// iter jsonfor (rapidjson::Value::ConstMemberIterator iter = dom.MemberBegin(); iter != dom.MemberEnd(); ++iter) {fprintf(stdout, "iter json name: %s, type: %d\n", iter->name.GetString(), iter->value.GetType());}return 0;
}int test_rapidjson_write()
{rapidjson::StringBuffer buf;//rapidjson::Writer<rapidjson::StringBuffer> writer(buf);rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf); // it can word wrapwriter.StartObject();writer.Key("name"); writer.String("spring");writer.Key("address"); writer.String("北京");writer.Key("age"); writer.Int(30);writer.Key("value1");writer.StartArray();writer.StartArray();writer.StartObject();writer.Key("name"); writer.String("spring");writer.Key("address"); writer.String("北京");writer.Key("age"); writer.Int(30);writer.Key("value1");writer.StartArray();writer.StartArray();writer.Double(23); writer.Double(43); writer.Double(-2.3); writer.Double(6.7);     writer.Double(90);writer.EndArray();writer.StartArray();writer.Int(-9); writer.Int(-19); writer.Int(10); writer.Int(2);writer.EndArray();writer.StartArray();writer.Int(-5); writer.Int(-55);writer.EndArray();writer.EndArray();writer.Key("value2");writer.StartArray();writer.Double(13.3); writer.Double(1.9); writer.Double(2.10);writer.EndArray();writer.Key("bei_jing");writer.StartObject();writer.Key("address"); writer.String("海淀");writer.Key("car"); writer.Bool(false);writer.Key("cat"); writer.Bool(true);writer.EndObject();writer.Key("shan_dong");writer.StartObject();writer.Key("address"); writer.String("济南");writer.Key("value1");writer.StartArray();writer.Key("ji_nan"); writer.String("趵突泉");writer.Key("tai_an"); writer.String("泰山");writer.EndArray();writer.EndObject();writer.EndObject();const char* json_content = buf.GetString();fprintf(stdout, "json content: %s\n", json_content);#ifdef _MSC_VERconst char* file_name = "E:/GitCode/Messy_Test/testdata/out.json";
#elseconst char* file_name = "testdata/out.json";
#endifstd::ofstream outfile;outfile.open(file_name);if (!outfile.is_open()) {fprintf(stderr, "fail to open file to write: %s\n", file_name);return -1;}outfile << json_content << std::endl;outfile.close();return 0;
}

json.data内容如下:

{"name": "spring","address": "北京","age": 30,"value1": [[23, 43, -2.3, 6.7, 90],[-9, -19, 10, 2],[-5, -55]],"value2": [13.3, 1.9, 2.10],"bei_jing": {"address": "海淀","car": false,"cat": true},"shan_dong": {"address": "济南","value1": [{"ji_nan": "趵突泉"}, {"tai_an": "泰山"}]}
}

test_rapidjson_parse的执行结果如下:与实际结果一致

test_rapidjson_write的执行结果如下:与预期一致,将rapidjson::Writer<rapidjson::StringBuffer> writer(buf)调整为rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);可使结果自动换行

GitHub:https://github.com/fengbingchun/Messy_Test

相关文章:

高德地图关键字搜索oc版

.h文件 // MapSearchViewController.h // JMT // // Created by walker on 16/10/11. // Copyright © 2016年 BOOTCAMP. All rights reserved. // #import <UIKit/UIKit.h> #import <AMapNaviKit/MaMapKit.h> #import <AMapSearchKit/AMapSearchKit.h&…

同一个内容,对比Java、C、PHP、Python的代码量,结局意外了

为什么都说Python容易上手&#xff01;是真的吗&#xff1f;都说Python通俗易懂&#xff0c;容易上手&#xff0c;甚至不少网友表示「完成同一个任务&#xff0c;C 语言要写 1000 行代码&#xff0c;Java 只需要写 100 行&#xff0c;而 Python 可能只要 20 行」到底是真的还是…

图片存储思考:

http://blog.csdn.net/liuruhong/article/details/4072386

LIVE555中RTSP客户端接收媒体流分析及测试代码

LIVE555中testProgs目录下的testRTSPClient.cpp代码用于测试接收RTSP URL指定的媒体流&#xff0c;向服务器端发送的命令包括&#xff1a;DESCRIBE、SETUP、PLAY、TERADOWN。 1. 设置使用环境&#xff1a;new一个BasicTaskScheduler对象&#xff1b;new一个BasicUsageEnvironm…

swift代理传值

比如我们这个场景&#xff0c;B要给A传值&#xff0c;那B就拥有代理属性&#xff0c; A就是B的代理&#xff0c;很简单吧&#xff01;有代理那就离不开协议&#xff0c;所以第一步就是声明协议。在那里声明了&#xff1f;谁拥有代理属性就在那里声明&#xff0c;所以代码就是这…

重磅:腾讯正式开源图计算框架Plato,十亿级节点图计算进入分钟级时代

整理 | 唐小引 来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;腾讯开源进化 8 年&#xff0c;进入爆发期。 继刚刚连续开源 TubeMQ、Tencent Kona JDK、TBase、TKEStack 四款重点开源项目后&#xff0c;腾讯开源再次迎来重磅项目&#xff01;北京时间 11 月 14 日…

类似ngnix的多进程监听用例

2019独角兽企业重金招聘Python工程师标准>>> 多进程监听适合于短连接&#xff0c;且连接间无交集的应用。前两天简单写了一个&#xff0c;在这里保存一下。 #include <sys/types.h>#include <stdarg.h>#include <signal.h>#include <unistd.h&…

今日头条李磊等最新论文:用于文本生成的核化贝叶斯Softmax

译者 | Raku 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;摘要用于文本生成的神经模型需要在解码阶段具有适当词嵌入的softmax层&#xff0c;大多数现有方法采用每个单词单点嵌入的方式&#xff0c;但是一个单词可能具有多种意义&#xff0c;在不同的背景下&#…

FFmpeg中RTSP客户端拉流测试代码

之前在https://blog.csdn.net/fengbingchun/article/details/91355410中给出了通过LIVE555实现拉流的测试代码&#xff0c;这里通过FFmpeg来实现&#xff0c;代码量远小于LIVE555&#xff0c;实现模块在libavformat。 在4.0及以上版本中&#xff0c;FFmpeg有了些变动&#xff…

虚拟机下运行linux通过nat模式与主机通信、与外网连接

首先&#xff1a;打开虚拟机的编辑菜单下的虚拟网络编辑器&#xff0c;选中VMnet8 NAT模式。通过NAT设置获取网关IP&#xff0c;通过DHCP获取可配置的IP区间。同时&#xff0c;将虚拟机的虚拟机菜单的设置选项中的网络适配器改为NAT模式。即可&#xff01; 打开linux&#xff0…

远程过程调用RPC简介

RPC(Remote Procedure Call, 远程过程调用)&#xff1a;是一种通过网络从远程计算机程序上请求服务&#xff0c;而不需要了解底层网络技术的思想。 RPC是一种技术思想而非一种规范或协议&#xff0c;常见RPC技术和框架有&#xff1a; (1). 应用级的服务框架&#xff1a;阿里的…

iOS开发:沙盒机制以及利用沙盒存储字符串、数组、字典等数据

iOS开发&#xff1a;沙盒机制以及利用沙盒存储字符串、数组、字典等数据 1、初识沙盒&#xff1a;(1)、存储在内存中的数据&#xff0c;程序关闭&#xff0c;内存释放&#xff0c;数据就会丢失&#xff0c;这种数据是临时的。要想数据永久保存&#xff0c;将数据保存成文件&am…

支撑亿级用户“刷手机”​,百度Feed流背后的新技术装备有多牛?

导读&#xff1a;截止到2018年底&#xff0c;我国网民使用手机上网的比例已高达98.6%&#xff0c;移动互联网基本全方位覆盖。智能手机的操作模式让我们更倾向于通过简单的“划屏”动作&#xff0c;相对于传统的文本交互方式来获取信息&#xff0c;用户更希望一拿起手机就能刷到…

玩转高性能超猛防火墙nf-HiPAC

中华国学&#xff0c;用英文讲的&#xff0c;稀里糊涂听了个大概&#xff0c;不得不佩服西方人的缜密的逻辑思维&#xff0c;竟然把玄之又玄的道家思想说的跟牛顿定律一般&#xff0c;佩服。归家&#xff0c;又收到了邮件&#xff0c;还是关于nf-hipac的&#xff0c;不知不觉就…

ios 沙盒 plist 数据的读取和存储

plist 只能存储基本的数据类型 和 array 字典 [objc] view plaincopy - (void)saveArray { // 1.获得沙盒根路径 NSString *home NSHomeDirectory(); // 2.document路径 NSString *docPath [home stringByAppendingPathComponent:"Document…

FFmpeg实现获取USB摄像头视频流测试代码

通过USB摄像头(注&#xff1a;windows7/10下使用内置摄像头&#xff0c;linux下接普通的usb摄像头(Logitech))获取视频流用到的模块包括avformat和avdevice。头文件仅include avdevice.h即可&#xff0c;因为avdevice.h中会include avformat.h。libavdevice库是libavformat的一…

重磅!明略发布数据中台战略和三大解决方案

11月15日&#xff0c;明略科技在上海举办以“FASTER 聚变增长新动力”为主题的2019数据智能峰会&#xff0c;宣布“打造智能时代的企业中台”新战略&#xff0c;同时推出了两大新产品“新一代数据中台”和“营销智能平台”&#xff0c;以及三大行业解决方案&#xff0c;分别是“…

Android程序完全退出的三种方法

1. Dalvik VM的本地方法 android.os.Process.killProcess(android.os.Process.myPid()) //获取PID&#xff0c;目前获取自己的也只有该API&#xff0c;否则从/proc中自己的枚举其他进程吧&#xff0c;不过要说明的是&#xff0c;结束其他进程不一定有权限&#xff0c;不然就…

FFmpeg通过摄像头实现对视频流进行解码并显示测试代码(旧接口)

这里通过USB摄像头(注&#xff1a;windows7/10下使用内置摄像头&#xff0c;linux下接普通的usb摄像头(Logitech))获取视频流&#xff0c;然后解码&#xff0c;最后再用opencv显示。用到的模块包括avformat、avcodec和avdevice。libavdevice库是libavformat的一个补充库(comple…

IOS数据存储之文件沙盒存储

前言&#xff1a; 之前学习了数据存储的NSUserDefaults&#xff0c;归档和解档&#xff0c;对于项目开发中如果要存储一些文件&#xff0c;比如图片&#xff0c;音频&#xff0c;视频等文件的时候就需要用到文件存储了。文件沙盒存储主要存储非机密数据&#xff0c;大的数据。 …

剖析Focal Loss损失函数: 消除类别不平衡+挖掘难分样本 | CSDN博文精选

作者 | 图像所浩南哥来源 | CSDN博客论文名称&#xff1a;《 Focal Loss for Dense Object Detection 》论文下载&#xff1a;https://arxiv.org/pdf/1708.02002.pdf论文代码&#xff1a;https://github.com/facebookresearch/Detectron/tree/master/configs/12_2017_baselines…

windows下mysql开启慢查询

mysql在windows系统中的配置文件一般是my.ini,我的路径是c:\mysql\my.ini,你根据自己安装mysql路径去查找[mysqld]#The TCP/IP Port the MySQL Server will listen onport3306#开启慢查询log-slow-queries E:\Program Files\MySQL\MySQL Server 5.5\mysql_slow_query.loglong_…

FFmpeg通过摄像头实现对视频流进行解码并显示测试代码(新接口)

在https://blog.csdn.net/fengbingchun/article/details/93975325 中给出了通过旧接口即FFmpeg中已废弃的接口实现通过摄像头获取视频流然后解码并显示的测试代码&#xff0c;这里通过使用FFmpeg中的新接口再次实现通过的功能&#xff0c;主要涉及到的接口函数包括&#xff1a;…

iOS经典讲解之获取沙盒文件路径写入和读取简单对象

#import "RootViewController.h" interface RootViewController () end 实现文件&#xff1a; implementation RootViewController - (void)viewDidLoad { [super viewDidLoad]; [self path]; [self writeFile]; [self readingFi…

Google最新论文:Youtube视频推荐如何做多目标排序

作者 | 深度传送门来源 | 深度传送门&#xff08;ID:deep_deliver&#xff09;导读&#xff1a;本文是“深度推荐系统”专栏的第十五篇文章&#xff0c;这个系列将介绍在深度学习的强力驱动下&#xff0c;给推荐系统工业界所带来的最前沿的变化。本文主要介绍下Google在RecSys …

Jmeter 笔记

Apache JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试&#xff0c;它最初被设计用于Web应用测试但后来扩展到其他测试领域。 它可以用于测试静态和动态资源例如静态文件、Java 小服务程序、CGI 脚本、Java 对象、数据库&#xff0c; FTP 服务器&#…

王贻芳院士:为什么中国要探究中微子实验?

演讲嘉宾 | 王贻芳&#xff08;中国科学院院士、中科院高能物理研究所所长&#xff09;整理 | 德状出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;日前&#xff0c;在2019腾讯科学WE大会期间&#xff0c;中国科学院院士、高能物理研究所所长王贻芳分享了中微子与光电…

一个苹果证书供多台电脑开发使用——导出p12文件

摘要 在苹果开发者网站申请的证书&#xff0c;是授权mac设备的开发或者发布的证书&#xff0c;这意味着一个设备对应一个证书&#xff0c;但是99美元账号只允许生成3个发布证书&#xff0c;两个开发证书&#xff0c;这满足不了多mac设备的使用&#xff0c;使用p12文件可以解决这…

FFmpeg中AVDictionary介绍

FFmpeg中的AVDictionary是一个结构体&#xff0c;简单的key/value存储&#xff0c;经常使用AVDictionary设置或读取内部参数&#xff0c;声明如下&#xff0c;具体实现在libavutil模块中的dict.c/h&#xff0c;提供此结构体是为了与libav兼容&#xff0c;但它实现效率低下&…

RocketMQ3.2.2生产者发送消息自动创建Topic队列数无法超过4个

问题现象RocketMQ3.2.2版本&#xff0c;测试时尝试发送消息时自动创建Topic&#xff0c;设置了队列数量为8&#xff1a;producer.setDefaultTopicQueueNums(8);同时设置broker服务器的配置文件broker.properties&#xff1a;defaultTopicQueueNums16但实际创建后从控制台及后台…