Rapidjson的使用过程-Parse解析数组遇到的问题,附自己的解决方式

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 关于RapidJSON,网上有很多资料,RapidJSON是腾讯开源的一个高效的C++ JSON解析器及生成器,它是只有头文件的C++库。RapidJSON是跨平台的,支持Windows, Linux, Mac OS X及iOS, Android。它的源码在https://github.com/Tencent/rapidjson/。这里也不过多介绍如何使用RapidJson,网上有很多如何使用,只介绍自己使用过程中遇到的问题,及其解决问题的方式。

RapidJson 数组使用的问题


简单介绍

应用环境说明

错误说明

结论


简单介绍

关于RapidJSON,网上有很多资料,RapidJSON是腾讯开源的一个高效的C++ JSON解析器及生成器,它是只有头文件的C++库。RapidJSON是跨平台的,支持Windows, Linux, Mac OS X及iOS, Android。它的源码在https://github.com/Tencent/rapidjson/。这里也不过多介绍如何使用RapidJson,网上有很多如何使用,只介绍自己使用过程中遇到的问题,及其解决问题的方式。


应用环境说明

在我们的日常开发中,大多数项目都需要与数据库打交道,在多人同时开发一个项目时,不同的人有不同的分工,一般的MS项目,通常至少有一个负责数据库的开发,然后将数据库的操作封装成具体的接口,在给后端应用开发人员使用,这样,不管后端开发人员与数据库接口的开发人员是不是使用同一语言开发都无关紧要,只要数据库开发人员提供完善的接口给应用开发人员即可,比如我现在所在的公司,数据库开发人员使用的mysql + mybits + java语言提供接口(类似这种形式的接口:http://192.168.2.161:8080/JMVC/asset_excute/getFormworkById.r?formworkId=1),接口形式遵从http协议,如果直接使用网页访问接口,返回的实际上就是JSON数据(查询数据库的结果),作为一名C++后台开发人员,很多时候都是获取这些JSON数据,然后展示给用户,如何在C++调用这种接口呢,我也很少去摸索,目前使用的是比较出名的libcurl,关于libcurl的使用和说明这里就不介绍了,网上有很多,如果你足够牛逼和网络知识足够(PS:本文适合新手,估计看到的写一个网络协议搞定这个也不会看这个博客了),如果热爱学习,这里有很多C++开源库和工具,真是一些好东西:开源库集合。


错误说明

在项目开发中,前端需要存取一些数据项(代码里封装成一个结构体P_PLANDRILL_TEMPLATE_W,结构体如下图所示,结构体中包含id和一些字符串字段,另外还包含一个vector,对应JSON数据的结构体数组)

在以下代码中,我们通过Rapidjson的Document类,解析我们想要解析一段json文本(对应结构体的字段,代码里的PC_JSON_TEMPLATE2,其中T_DUTYRESPONSE_TEMPLATE的chDutyUserNames和chPlanDrillRecord字段没有对应,formworkDivides的title对应chDutyName,duty对应chDutyResponse,其中C_NEW_PLANDRILL_OPERATION_Handler是我的一个类)
static const char* PC_JSON_TEMPLATE1 = "{\"id\":0,\"title\":\"\",\"purpose\":\"\",
\"objective\":\"\",\"scene\":\"\",\"createUser\":\"\"}";//测试数据json数据1
static const char* PC_JSON_TEMPLATE2 = "{\"id\":0,\"title\":\"\",\"purpose\":\"\",\"objective\":\"\",\"scene\":\"\",\"
createUser\":\"\",\"formworkDivides\":[{\"title\":\"\",\"duty\":\"\"},{\"title\":"",\"duty\":""}]}";//测试json数据2
int C_NEW_PLANDRILL_OPERATION_Handler::ExcuteRequest(void * pReqParam, int nReqSize, int * pnResultCount)
{
  //分析参数
  if (nReqSize != sizeof(P_PLANDRILL_TEMPLATE_W) || pReqParam == NULL)
  {
  return ERR_CODE_WRONG_PARAM;
  }
  auto p_PLANDRILL_TEMPLATE = static_cast<LP_PLANDRILL_TEMPLATE_W>(pReqParam);//获取从客户端传来的参数
  m_dutyResponseSize = p_PLANDRILL_TEMPLATE->listDutyResponse.size();
  //构造参数
  Document doc; //Document 是rapidJson库的核心文档类,请参考官网使用说明
  //以下注释的代码,是错误说明,没有通过该种方式成功设置值,
  //~~目前不知道是rapidjson自身的问题,还是我使用的问题(以上PC_JSON_TEMPLATE2格式没有问题)
  //也可能是我使用的rapidjson版本比较老,rapidjson的确存在这个问题,但是已经修复这个问题~~ 
  //如果使用PC_JSON_TEMPLATE2,在运行时,走到if处会抛出异常,并不能正确设置值,目前还没找到原因
  //doc.Parse(PC_JSON_TEMPLATE1);
  //char pcUTF[2048] = { 0 };
  //if (doc.HasMember("id") && doc["id"].IsInt()) 
  //{
  //  g_pLogger->WriteLog("有id字段并且id字段是int", "", 0, ""); 
  //  doc["id"].SetInt(p_PLANDRILL_TEMPLATE->id);//设置id字
  //}
    //以下代码能够正确设置从前端获取的值,并通过libcurl将数据存到数据库
  doc.SetObject();
  Document::AllocatorType& allocator = doc.GetAllocator();//生成一个分配器
  doc.AddMember("id", p_PLANDRILL_TEMPLATE->id, allocator);
  doc.AddMember("title", StringRef(p_PLANDRILL_TEMPLATE->chTitle), allocator);
  doc.AddMember("purpose", StringRef(p_PLANDRILL_TEMPLATE->chPurpose), allocator);
  doc.AddMember("objective", StringRef(p_PLANDRILL_TEMPLATE->chObjective), allocator);
  doc.AddMember("scene", StringRef(p_PLANDRILL_TEMPLATE->chScene), allocator);
  doc.AddMember("createUser", StringRef(p_PLANDRILL_TEMPLATE->chCreateUser), allocator);
  //生成职务列表
  rapidjson::Value ObjectArray(rapidjson::kArrayType);
  for (int i = m_dutyResponseSize - 1; i >= 0; --i)
  {
  rapidjson::Value obj(rapidjson::kObjectType);
  obj.AddMember("title", StringRef(p_PLANDRILL_TEMPLATE->listDutyResponse[i].chDutyName), allocator);
  obj.AddMember("duty", StringRef(p_PLANDRILL_TEMPLATE->listDutyResponse[i].chDutyResponse), allocator);
  ObjectArray.PushBack(obj, allocator);
  }
  doc.AddMember("formworkDivides", ObjectArray, allocator);
  StringBuffer s;
  Writer<StringBuffer> writer(s);
  doc.Accept(writer);
  //发送请求并解析
  //调用libcurl保存数据到数据库
  int nRet = DoRequest(JSON_SERVER_URI, IS_POST_METHOD, s.GetString() , s.GetSize());
  if (nRet == 0)
  {
  *pnResultCount = m_szResultCount;
  }
}


结论

我目前在使用rapidjson过程中,就遇到过这样的一个问题,及其遇到问题的解决方式都在代码里做了详细说明,如果网友有跟我一样的情况,可以参考该博客使用Rapidjson生成JSON的使用方式RapidJSON生成json格式文件,而不应该使用字符串拼接的方式或者将其字符串写死来进行解析,这样很有可能就会导致莫名其妙的错误

PS:该文只是自己使用rapidjson的一点心得体会和使用过程中遇到的问题,适合刚刚学习rapidjson的同学。另外希望大家能够共同学习,把在工作中遇到的问题提出来,大家一起解决。


相关文章
|
6月前
|
C语言
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
|
2月前
|
JavaScript
js 解析 byte数组 成字符串
js 解析 byte数组 成字符串
68 5
|
29天前
|
人工智能 前端开发 JavaScript
拿下奇怪的前端报错(一):报错信息是一个看不懂的数字数组Buffer(475) [Uint8Array],让AI大模型帮忙解析
本文介绍了前端开发中遇到的奇怪报错问题,特别是当错误信息不明确时的处理方法。作者分享了自己通过还原代码、试错等方式解决问题的经验,并以一个Vue3+TypeScript项目的构建失败为例,详细解析了如何从错误信息中定位问题,最终通过解读错误信息中的ASCII码找到了具体的错误文件。文章强调了基础知识的重要性,并鼓励读者遇到类似问题时不要慌张,耐心分析。
|
3月前
|
存储 JavaScript 前端开发
一文带你深度解析:JavaScript中对象与数组的威力究竟有多大?
一文带你深度解析:JavaScript中对象与数组的威力究竟有多大?
|
5月前
|
存储 算法 搜索推荐
深入解析String数组的操作与性能优化策略
深入解析String数组的操作与性能优化策略
|
4月前
|
存储 算法 搜索推荐
深入解析String数组的操作与性能优化策略
深入解析String数组的操作与性能优化策略
|
5月前
|
存储 Java 数据库
解析和使用String数组的方法
解析和使用String数组的方法
指针与数组笔试题解析
指针与数组笔试题解析
|
5月前
|
存储 JavaScript 前端开发
JavaScript——JavaScript基础:数组 | JavaScript函数:使用、作用域、函数表达式、预解析
在JavaScript中,内嵌函数可以访问定义在外层函数中的所有变量和函数,并包括其外层函数能访问的所有变量和函数。①全局变量:不在任何函数内声明的变量(显式定义)或在函数内省略var声明的变量(隐式定义)都称为全局变量,它在同一个页面文件中的所有脚本内都可以使用。函数表达式与函数声明的定义方式几乎相同,不同的是函数表达式的定义必须在调用前,而函数声明的方式则不限制声明与调用的顺序。③块级变量:ES 6提供的let关键字声明的变量称为块级变量,仅在“{}”中间有效,如if、for或while语句等。
55 0
|
6月前
|
C语言
C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)(上)
C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)
42 0

推荐镜像

更多