avatar

目录
JsonCpp中文文档(更新中...)

JSON数据的广泛使用使我们都认识到了json的便捷性,可新版jsoncpp得到其他教程基本灭亡,没办法自己来翻译一个吧!

github:https://github.com/open-source-parsers/jsoncpp/

一、啥是JSONCPP

### 1、介绍

JSON是一种轻量级的数据交换格式

下面是json数据的示例

1
2
3
4
5
6
7
8
9
10
{ 
"encoding": "UTF-8",
"plugins":[
"python",
"C++",
"ruby",
...
],
"indent":{ "length":3, "use_space":true}
}

JsonCpp支持将注释作为元数据

json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Configuration options
{
// Default encoding for text
"encoding" : "UTF-8",

// Plug-ins loaded at start-up
"plug-ins" : [
"python",
"c++", // trailing comment
"ruby"
],

// Tab indent size
// (multi-line comment)
"indent" : { /*embedded comment*/ "length" : 3, "use_space": true }
}

下面开始介绍jsoncpp的基本功能

### 2、特点

  • 读写JSON文档
  • 在解析期间将C++样式注释添加到元素
  • 重写JSON文档,并保留注释

注意:注释以前在JSON中受支持,但由于可移植性而被删除(Python不支持类似C的注释)。由于注释在配置/输入文件中很有用,因此保留了此功能。

代码示例

cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Json::Value root;   // 'root' 将作为JSON数据的根节点.

// 你可以在外部写入子节点
std::cin >> root;
// 也可以给子节点,写入新节点
std::cin >> root["subtree"];

// 获取节点名为 "encoding" 节点的子节点,如果没有就返回“UTF-8”
std::string encoding = root.get("encoding", "UTF-8" ).asString();

// 获取节点为“plug-ins”的子节点,没有就返回NULL
const Json::Value plugins = root["plug-ins"];
// 可以遍历节点
for ( int index = 0; index < plugins.size(); ++index )
loadPlugIn( plugins[index].asString() );

// 可以通过asInt/asBool一类函数将数据转换成需要的数据类型
foo::setIndentLength( root["indent"].get("length", 3).asInt() );
foo::setIndentUseSpace( root["indent"].get("use_space", true).asBool() );

// 由于Json::Value对所有值类型都有一个隐式构造函数,因此不必显式构造Json::Value对象。
root["encoding"] = foo::getCurrentEncoding();
root["indent"]["length"] = foo::getCurrentIndentLength();
root["indent"]["use_space"] = foo::getCurrentIndentUseSpace();

// 如果你喜欢默认的你可以直接插入
std::cout << root;

// 当然,如果您愿意的话,可以写入“std::ostringstream”。如果需要,记得添加换行和刷新。
std::cout << std::endl;

高级用法

配置构建器(builders),用来穿件 readers 和 writers对象。

对于配置,我们使用自己的Json::Value(然不是标准的setters/getter)这样我们就可以添加特性而不会失去二进制兼容性.

cpp
1
2
3
4
5
6
7
8
9
10
// 为了方便起见,请将“writeString()”与专用生成器一起使用
Json::StreamWriterBuilder wbuilder;
wbuilder["indentation"] = "\t";
std::string document = Json::writeString(wbuilder, root);

// 在这里,我们使用一个专用的构建器,在解析时丢弃注释并记录错误,换句话说就是配置解析器
Json::CharReaderBuilder rbuilder;
rbuilder["collectComments"] = false;
std::string errs;
bool ok = Json::parseFromStream(rbuilder, std::cin, &root, &errs);

是的,编译时配置检查会有帮助,但是Json::Value允许您编写和读取生成器配置,这更好!换句话说,您可以使用JSON配置JSON解析器。

CharReaders和streamwriter不是线程安全的,但它们是可重用的。

cpp
1
2
3
4
5
6
7
Json::CharReaderBuilder rbuilder;
cfg >> rbuilder.settings_;
std::unique_ptr const reader(rbuilder.newCharReader());
reader->parse(start, stop, &value1, &errs);
// ...
reader->parse(start, stop, &value2, &errs);
// etc.

二、JSONCPP基本用法(持续更新)

1、创建基本的JSON数据格式

cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cout << "=====================创建一个json格式数据=====================" << endl;
//创建一个json格式数据

Json::Value root;
root["null"] = NULL; //注意此处在输出是显示为0,而非null
root["message"] = "OK";
root["age"] = 52;
root["array"].append("arr"); // 新建一个key为array,类型为数组,对第一个元素赋值为字符串“arr”
root["array"].append(123); // 为数组 key_array 赋值,对第二个元素赋值为:1234

Json::ValueType type = root.type(); //root的类型

cout << root.toStyledString() << endl; //格式化输出
cout << "root_type:" << type << endl; //类型为7,即为类型为对象
cout << root["message"].asString() << endl; //类型为7,即为类型为对象

image-20200512154018595

2、序列化JSON数据格式

cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cout << "===================字符串实例化成JSON数据===================" << endl;
const char* str = "{\"name\":\"毛毛\",\"age\":18}";
// 实例化一个容器
Json::CharReaderBuilder builder;
Json::CharReader* reader(builder.newCharReader());
Json::Value root;
JSONCPP_STRING errs;
bool isOK = reader->parse(str, str + strlen(str), &root, &errs);
if (isOK && errs.size() == 0)
{
string upload_id = root["uploadid"].asString(); // 访问节点,upload_id = "UP000000"
int code = root["code"].asInt(); // 访问节点,code = 100
}
delete reader;
cout << root.toStyledString() << endl;
cout << "姓名:" << root["name"].asString() << "=====年龄:" <"age"] << endl;

image-20200512153840842

3、将JSON数据写入文本

cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Json::Value jsonRoot;
Json::Value jsonItem;
jsonItem["item1"] = "第一个";
jsonItem["item2"] = "第二个";
jsonRoot.append(jsonItem);
jsonItem.clear();//清除上面已经赋值的项
jsonItem["First"] = "1";
jsonItem["Second"] = 2;
jsonItem["Third"] = 3.0F;
jsonRoot.append(jsonItem);

ofstream ofs;
ofs.open("test1.json");
ofs << jsonRoot.toStyledString() << endl;
ofs.close();

4、将JSON文件读入程序

cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//C:/Users/Administrator/Desktop
string sJson = jsonRoot.toStyledString();
jsonRoot.clear();
// 创建一个暂存容器
Json::CharReaderBuilder builder;
// 接收数据
Json::Value root;
// 接收错误数据
JSONCPP_STRING errs;
// 打开文件流
ifstream ifs;
ifs.open("C:/Users/Administrator/Desktop/test.json");

// 核心代码
bool parse_ok = Json::parseFromStream(builder, ifs, &root, &errs);
ifs.close();
if (!parse_ok)
{
cout << "打开文件出错" << endl;
}
else
{
cout << root.toStyledString() << endl;
}

三、工具点

1、解析 json 字符串

1将json输出的数据转换成指定数据类型

函数 得到的值
asBool() 布尔型 bool
asInt() 整型 int
asInt64() 64位整型 long long
asUInt() 无符号整型 unsigned int
asUInt64() 64位无符号整型 unsigned long long
asLargestInt() 最大位数的整型 intmax_t
asLargestUInt() 最大位数的无符号整型 uintmax_t
asFloat() 浮点数 float
asDouble() 双精度浮点数 double
asString() 字符串 std::string
asCString() 字符串 const char *

2、判断 Json::Value 的类型

Json::Value 的 type() 方法返回的是 Json::Value 的类型。

类型枚举值 说明
nullValue NULL 值
intValue 有符号整数
uintValue 无符号整数
realValue 双精度浮点数
stringValue UTF-8 字符串
booleanValue 布尔值
arrayValue 数组
objectValue 一组 name/value 键值对

Json::Value数据类型的另外一种判断方法IsXXX

判断类型的方法 说明
isNull() 是 NULL 值
isBool() 是布尔值
isNumeric() 是数字
isIntegral() 是整数
isInt() 是有符号整数
isInt64() 是 64 位有符号整数
isUInt() 是无符号整数
isUInt64() 是 64 位无符号整数
isDouble() 是浮点数
isString() 是字符串
isArray() 是数组
isObject() 是 name/value 键值对
文章作者: Abraverman
文章链接: http://abraverman.gitee.io/2020/05/12/json-cpp/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Abraverman
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论