极力推荐一个简单好用的 C++JSON 库 CJsonObject, 让使用 JSON 如使用 C++ 原生的结构体那般方便, 随心所欲. https://github.com/Bwar/CJsonObject 是个优秀的 C++JSON 库, 也许会是你见过的最为简单易用的 C++JSON 库. CJsonObject 的开源地址是 https://github.com/Bwar/CJsonObject 和 https://gitee.com/Bwar/CJsonObject . 在开源之初发布的一篇介绍 CJsonObject 使用的博客《轻量简单好用的 C++JSON 库 CJsonObject》 https://my.oschina.net/cqcbw/blog/1844575 .
CJsonObject 开源一年, 没有刻意推广, 在 GitHub 上获得 130 多 star 和 60 多 fork, 事实上当初把 CJsonObject 开源并建立一个与 cJSON 的 fork 关系 (事实上 CJsonObject 与 GitHub 上的 cJSON 没有任何关系, CJsonObject 使用的 cJSON 是基于 SourceForge 上版本比较老的 cJSON 基础上修改的) 是为了多引入一些流量到 Bwar 倾力打造的另一开源项目 Nebula https://gitee.com/Bwar/nebula . 没想到, 倾力打造并且写了好几篇有技术含量的博客文章来推广的 Nebula 无论 star 数量还是 fork 数量都比 CJsonObject 少(可能跟受众数量有关系).Bwar 始终认为绝大部分使用 JSON 的场景下, 易用性与开发效率才是第一位的, 而不是解析性能. 在易用性上, 说 CJsonObject 让 JSON 如 C++ 原生数据结构一般并不为过, 所以不避黄婆卖瓜之嫌再极力推荐! CJsonObject 有良好的更新和维护, 对使用者提的 issue 响应非常及时, 开源一年增加了不少原本不支持但使用者又需要的功能特性.
CJsonObject 在 Bwar 的重点开源项目 Nebula 中大量使用, 无论对 Bwar 自己还是对外部开发者, 都有持续更新维护的需要. 顺便为打个小广告, Nebula https://gitee.com/Bwar/nebula 是一个强大的 IoC 网络框架, 用于以 C++ 快速构建高并发, 分布式和弹性的消息驱动应用程序. 适用于即时通讯, 数据采集, 实时计算, 消息推送, web 后台服务等应用场景, Nebula 已有即时通讯, 埋点数据采集及实时分析的生产应用案例. 如果觉得 CJsonObject 不错, 给 Nebula https://gitee.com/Bwar/nebula 也点个 star, 谢谢.
https://github.com/Bwar/CJsonObject 是基于 cJSON 全新开发一个 C++ 版的 JSON 库, CJsonObject 的最大优势是轻量, 简单好用, 开发效率极高. CJsonObject 只有 4 个文件, 拷贝到自己代码里源码级集成即可, 无须编译成库, 且跨平台和编译器. 与大部分 JSON 解析库访问多层嵌套 JSON 非常麻烦不同, CJsonObject 对多层嵌套 JSON 的读取和生成使用非常简单.
针对开发者在博客和 CJsonObject 项目的 issue 提的问题整理了一个 FAQ 如下:
FAQ
1. 如何遍历 JSON 的 key, 并取其 value?
- std::string strTraversingKey;
- std::string strTraversingValue;
- while(oJson.GetKey(strTraversingKey))
- {
- if (oJson.Get(strTraversingKey, strTraversingValue))
- {
- std::cout << strTraversing << ":" << strTraversingValue << std::endl;
- }
- }
GetKey()遍历不适用于数组, 对 JSON 数组调用 GetKey()将直接返回 false. 调用 GetKey()函数循环遍历获取当前所在层次的 JSON key,GetKey()返回 false 表示已取完最后一个 key, 下次遍历再调用 GetKey()将重新从第一个 key 开始获取. 换一种说法, GetKey()遍历 JSON key 的返回结果为: true,true,true ... true,false; true,true,true ... true,false; true,true,true ... true,false; 想要遍历多少轮完全由用户自己决定.
如果需要中断一次遍历并重新开始, 可以调用 ResetTraversing()函数重置遍历.
- std::string strTraversingKey;
- std::string strTraversingValue;
- while(oJson.GetKey(strTraversingKey))
- {
- if (strTraversingKey == "Auguest")
- {
- oJson.ResetTraversing();
- break;
- }
- if (oJson.Get(strTraversingKey, strTraversingValue))
- {
- std::cout << strTraversing << ":" << strTraversingValue << std::endl;
- }
- }
- // 因为上一个遍历中断时调用了 ResetTraversing(), 所以本次遍历又是从第一个 key 开始. 如果上一个遍历中断时未调用 ResetTraversing(), 那这次遍历将是从上次终端的位置继续, 这通常不是遍历的预期结果, 因此, 中断遍历时记得 ResetTraversing().
- while(oJson.GetKey(strTraversingKey))
- {
- if (oJson.Get(strTraversingKey, strTraversingValue))
- {
- std::cout << strTraversing << ":" << strTraversingValue << std::endl;
- }
- }
__注意:__对 JSON 当前层次的 key 进行 Add()或 Delete()操作, 将导致当前遍历失效, 下次调用 GetKey()将获取 key 从头开始.
2. Replace 一个 key 时, 是否需要原 value 类型与替换后 value 类型一致?
Replace()函数对 key 进行替换, 跟 value 类型无关. 把一个 value 为 int 的替换为 value 为 string, 或将 value 替换为 object 或 array 都是可以的. 但如非必要, 建议替换后的 value 类型跟替换前的 value 类型相同.
3. []和 () 的重载有什么区别, 为什么要重载这两个操作符?
[]的重载是操作 JsonObject 或 JsonArray 的, 为了方便一层一层往下取嵌套的 JSON, 不适用于 string,int 等基本 JSON 类型;()的重载是 Get()系列函数的更便捷的调用, 如果十分肯定 key 是存在的不需要通过 Get()的返回值判断是否获取成功, 调用 () 比调用 Get()编码要快, 不适用于操作 JsonObject 或 JsonArray.
[]和 () 返回值是不一样的, 两者不能混用.
4. 如何用 CJsonObject 创建类似以下二维数组?
- {
- "test":[
- [{"test":1}],
- [{"test":2}]
- ]
- }
CJsonObject 对多层嵌套 JSON 的操作非常灵活方便, 对嵌套 JSON 的生成和读取有许多种灵活用法.
- neb::CJsonObject oTest;
- oTest.AddEmptySubArray("test");
- for (int i = 1; i < 3; ++i)
- {
- neb::CJsonObject oDimension1;
- neb::CJsonObject oDimension2;
- oDimension2.Add("test", i);
- oDimension1.Add(oDimension2);
- oTest["test"].Add(oDimension1);
- }
- std::cout << oTest.ToString() << std::endl;
这里给出的只是其中一种写法, 其他几种可以参考 FAQ#5.
5. 请问一下在使用 CJsonObject 如何创建如下形式的数组?
- {
- "employees": [
- { "firstName":"John" , "lastName":"Doe" },
- { "firstName":"Anna" , "lastName":"Smith" },
- { "firstName":"Peter" , "lastName":"Jones" }
- ]
- }
这里给出三种生成上述 JSON 数组的方式:
- neb::CJsonObject oJson;
- oJson.AddEmptySubArray("employees");
- oJson["employees"].Add(neb::CJsonObject("{\"firstName\":\"John\", \"lastName\":\"Doe\"}"));
- oJson["employees"].Add(neb::CJsonObject("{\"firstName\":\"Anna\", \"lastName\":\"Smith\"}"));
- oJson["employees"].Add(neb::CJsonObject("{\"firstName\":\"Peter\", \"lastName\":\"Jones\"}"));
- neb::CJsonObject oJson;
- oJson.AddEmptySubArray("employees");
- oJson["employees"].Add(neb::CJsonObject("{}"));
- oJson["employees"][0].Add("firstName", "John");
- oJson["employees"][0].Add("lastName", "Doe");
- oJson["employees"].Add(neb::CJsonObject("{}"));
- oJson["employees"][1].Add("firstName", "Anna");
- oJson["employees"][1].Add("lastName", "Smith");
- oJson["employees"].Add(neb::CJsonObject("{}"));
- oJson["employees"][2].Add("firstName", "Peter");
- oJson["employees"][2].Add("lastName", "Jones");
- neb::CJsonObject oJson;
- neb::CJsonObject oJohn;
- neb::CJsonObject oAnna;
- neb::CJsonObject oPeter;
- oJohn.Add("firstName", "John");
- oJohn.Add("lastName", "Doe");
- oAnna.Add("firstName", "Anna");
- oAnna.Add("lastName", "Smith");
- oPeter.Add("firstName", "Peter");
- oPeter.Add("lastName", "Jones");
- oJson.AddEmptySubArray("employees");
- oJson["employees"].Add(oJohn);
- oJson["employees"].Add(oAnna);
- oJson["employees"].Add(oPeter);
来源: https://www.cnblogs.com/bwar/p/11294452.html