既然看到了这篇文章你肯定知道Json是什么东西了,网上有很多解析Json的开源库,最近工作需要用到Json解析,研究发现jsoncpp使用很方便,网上也有很多使用方法介绍,目前为止能查到的基本都是比较老的API使用方法,编译器会提醒使用的某些API已经被弃用了,有的编译器还会直接报错,既然推荐用新的那就学一下新API的使用方法吧,记录一下。

新发现一个更简单好用的json库,星星非常多,推荐用这个 nlohmann/json 。



JSONCPP是C++中的生成与解析JSON 字符串的一种实现。JSON是一种人比较容易理解,机器也比较容易解析的轻量级的数据交换格式。可以从Github上下载jsoncpp, https://github.com/open-source-parsers/jsoncpp。

使用方式

使用静态库/动态库

官方推荐使用Ninja进行编译,项目说明里有介绍。当然也可以使用比较常用的cmake进行编译

mkdir -p build/debug
cd build/debug
cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=ON -DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" ../..
make

生成的静/动态库文件目录为build/debug/src/lib_json/,使用的时候把include头文件加到工程中,链接使用-ljsoncpp参数指定链接库即可。

使用源文件

相比使用静态库,我更倾向于直接使用源文件,感觉这样比较方便。
在项目目录中直接执行python amalgamate.py命令,会在dist目录下生成两个头文件和一个源文件json-forwards.hjson.hjsoncpp.cpp。因为jsoncpp源码就四五千行,直接放在jsconcpp.cpp中和工程中其他代码一起编译也比较方便。

新API

这里随便写一个Json数据来演示,下面这个Json串包含了数组和内嵌Json串,一般常见的也就这样的吧。

{"Name": "Liming","Age": 26,"Language": ["C++", "Java"],"E-mail": {"Netease": "lmshao@163.com","Hotmail": "liming.shao@hotmail.com"}
}

生成Json字符串

#include <iostream>
#include "json/json.h"std::string createJson()
{std::string jsonStr;Json::Value root, lang, mail;Json::StreamWriterBuilder writerBuilder;std::ostringstream os;root["Name"] = "Liming";root["Age"] = 26;lang[0] = "C++";lang[1] = "Java";root["Language"] = lang;mail["Netease"] = "lmshao@163.com";mail["Hotmail"] = "liming.shao@hotmail.com";root["E-mail"] = mail;std::unique_ptr<Json::StreamWriter> jsonWriter(writerBuilder.newStreamWriter());jsonWriter->write(root, &os);jsonStr = os.str();std::cout << "Json:\n" << jsonStr << std::endl;return jsonStr;
}

调用这个函数会输出

Json:
{"Age" : 26,"E-mail" : {"Hotmail" : "liming.shao@hotmail.com","Netease" : "lmshao@163.com"},"Language" : ["C++","Java"],"Name" : "Liming"
}

解析Json字符串

解析Json的前提是我们知道这个Json字符串里面包含了哪些数据,针对上面函数生成的Json串,我们使用下面这个函数来解析其中的数据。

bool parseJson(const std::string &info)
{if (info.empty())return false;bool res;JSONCPP_STRING errs;Json::Value root, lang, mail;Json::CharReaderBuilder readerBuilder;std::unique_ptr<Json::CharReader> const jsonReader(readerBuilder.newCharReader());res = jsonReader->parse(info.c_str(), info.c_str()+info.length(), &root, &errs);if (!res || !errs.empty()) {std::cout << "parseJson err. " << errs << std::endl;}std::cout << "Name: " << root["Name"].asString() << std::endl;std::cout << "Age: " << root["Age"].asInt() << std::endl;lang = root["Language"];std::cout << "Language: ";for (int i = 0; i < lang.size(); ++i) {std::cout << lang[i] << " ";}std::cout << std::endl;mail = root["E-mail"];std::cout << "Netease: " << mail["Netease"].asString() << std::endl;std::cout << "Hotmail: " << mail["Hotmail"].asString() << std::endl;return true;
}

在main函数里面调用这个函数,以上一个函数的返回值作为输入参数会有如下输出:

Name: Liming
Age: 26
Language: "C++" "Java"
Netease: lmshao@163.com
Hotmail: liming.shao@hotmail.com

旧API

网上一搜多数都是旧API,懒得整理测试了,大概是这面这个样子。嵌套方式和上面新API操作一样。

生成Json

 Json::Value root, ex;Json::FastWriter writer;root["Name"] = "Lucy";root["age"] = 20;ex[0] = "ABC";ex[1] = "DEF";root["exinfo"] = ex;string json = writer.write(root);

解析Json

 Json::Reader reader;Json::Value root;const char *jsonStr = "{\"Name\":\"Lucy\",\"Age\":20}";if (!reader.parse(jsonStr, jsonStr + strlen(jsonStr), root)) {std::cout << "json parse failed\n";return 1;}std::string name = root["Name"].asString();int age = root["Age"].asInt();

使用旧API编译器有诸如下面的提醒,有点编译器会报warning,有的编译器会报error,

warning: 'Reader' is deprecated: Use CharReader and CharReaderBuilder instead [-Wdeprecated-declarations]warning: 'FastWriter' is deprecated: Use StreamWriterBuilder instead [-Wdeprecated-declarations]

坚持使用旧API可以在文件头部加入这段代码:

#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#elif defined(_MSC_VER)
#pragma warning(disable : 4996)
#endif

总结

可以把Json::Value理解为一个Json结构,这个类型可以嵌套,也可以当做数组一样使用,在需要的时候可以把这个结构转为相应的类型。
比如:
我们已经知道root["Name"]存放的是一个string,可以把使用.asString()转换为string类型;
知道root["Language"]这个Json::Value是一个数组,就可以像数组一样使用下标进行取值;
知道root["E-mail"]这个Json::Value里面是嵌套的一个json,就可以和root结构一样进行处理。
Json::Value其他的成员函数还有

// 转换类型
Int asInt() const;
UInt asUInt() const;
Int64 asInt64() const;
UInt64 asUInt64() const;
LargestInt asLargestInt() const;
LargestUInt asLargestUInt() const;
float asFloat() const;
double asDouble() const;
bool asBool() const;
// 检测类型
bool isNull() const;
bool isBool() const;
bool isInt() const;
bool isInt64() const;
bool isUInt() const;
bool isUInt64() const;
bool isIntegral() const;
bool isDouble() const;
bool isNumeric() const;
bool isString() const;
bool isArray() const;
bool isObject() const;

其他的自行查阅源码吧。

有错误麻烦指出,谢谢~

C++ JSON 库 jsoncpp 新API的使用方法(CharReaderBuilder / StreamWriterBuilder)相关推荐

  1. json库——jsoncpp

    一.jsoncpp简介 JsonCpp是一个开源的C++库,用于解析和生成JSON(JavaScript Object Notation)数据格式.JSON是一种轻量级的数据交换格式,广泛用于各种应用 ...

  2. 微信小程序2.9.0基础库canvas2D新API,生成海报保存到手机功能实现,包括文字换行,圆形图片,图片高度自适应等功能封装

    WxCanvas 利用canvas微信小程序原生实现的一个绘制微信小程序海报的类,基础库版本>2.9.0. 下面链接中使用的api已被废弃,所以有了本文. 微信小程序生成海报保存到手机 先看效果 ...

  3. Linux下Json库的编译及代码测试

    一.Json基础 JSON(JavascriptObject Notation)是一种轻量级的数据交换语言,以文字为基础,且易于让人阅读.尽管JSON是在Javascript的一个子集,但JSON是独 ...

  4. Play 2.0 用户指南 - 使用JSON库 -- 针对Scala开发者

    2019独角兽企业重金招聘Python工程师标准>>> 概述 使用JSON的推荐方式是使用 Play 的基于类的JSON库,位于play.api.libs.json下. 该库构建于J ...

  5. hbase建索引java api_hbase java api样例(版本1.3.1,新API)

    hbase版本:1.3.1 目的:HBase新API的使用方法. 尝试并验证了如下几种java api的使用方法. 1.创建表 2.创建表(预分区) 3.单条插入 4.批量插入 5.批量插入(客户端缓 ...

  6. hbase java api样例(版本1.3.1,新API)

    hbase版本:1.3.1 目的:HBase新API的使用方法. 尝试并验证了如下几种java api的使用方法. 1.创建表 2.创建表(预分区) 3.单条插入 4.批量插入 5.批量插入(客户端缓 ...

  7. C++用库 jsoncpp 解析 JSON

    使用C++处理JSON数据交换格式(转自http://hi.baidu.com/%D3%C3%B1%F8%C8%E7%C9%F1garbin/blog/item/85c602edd7f9a7fbcf1 ...

  8. Teams Bot 如何使用新的 System.Text.Json 库

    我最近把 LuckyDraw的代码升级到了 .net core 3.1,当然我也很想使用最新的微软json库,System.Text.Json这个库的性能比之前Newtonsoft.Json速度更快, ...

  9. Java JSON库Jackson 2 x新变化一览

    <Java JSON库Jackson 2.x新变化一览> 作者:chszs,转载需注明. 作者博客主页:http://blog.csdn.net/chszs Jackson库是JSON J ...

最新文章

  1. 使用html格式,通过php调用数据库并显示数据
  2. TensorFlow object detection api------ssd_mobilenet使用
  3. Linux与云计算——第二阶段 第五章:存储Storage服务器架设—分布式存储GlusterFS基础...
  4. LUA __call
  5. 机器学习之异常点检测
  6. DataWorks搬站方案:Airflow作业迁移至DataWorks
  7. Linux相关配置 集群免密码登录配置
  8. Ethercat解析(十三)之fsm_master状态机
  9. C语言库函数大全及应用实例三
  10. Linux系统配置jdk环境变量
  11. 前端模板inspinia
  12. ONMF正交非负矩阵分解·论文总结
  13. LaTeX中插入文本框并且设置文本框底色(填充色)的方法
  14. linux 命令无法Tab补全,命令参数无法补全
  15. Vue / axios / props 调用后端接口数据并渲染到页面
  16. Linux环境下 微信支付退款 读取证书路径问题
  17. UEBA对抗威胁之“健康就是财富”!
  18. 基于BB方案,荣耀观影眼镜Vision Glass正式发布
  19. HM编码器代码阅读(31)——帧间预测之AMVP/Merge模式(六)运动补偿
  20. android 蓝牙打印机(ESC/POS 热敏打印机),打印菜单小票和图片,对蓝牙配对和连接打印功能进行了封装,让你超快实现蓝牙打印功能

热门文章

  1. 【Pikachu】漏洞练习平台做题记录+原理解析(2.2)XSS姿势和技巧
  2. 命令行执行python文件_金木水火土命查询表
  3. SAARC的完整形式是什么?
  4. 【图示】30张图看懂中国金融体系
  5. ipad怎样和计算机连接网络,ipad怎么连接电脑教程 ipad怎么和电脑连接【详细步骤】...
  6. 用“生物进化论”来阐述“恶意代码进化论”
  7. Java编写满天星+月亮
  8. Android 单元测试 Mockito使用详解
  9. AsyncTask 异步任务基本使用--下载视频
  10. java学习资源大集锦