之前推荐过json组装和解析的开源库jsoncpp,今天推荐另一款json类库nlohmann,其以对于现代C 的支持度高而著称。
下载和安装
下载链接见(https://github.com/nlohmann/json),
针对github使用有一个小技巧,如果针对这类开源库仅仅是使用其源码,并不需要一直追踪源文件,可以选择代码页面右侧中部的Release部分,下载release版本的代码集成到自己的项目中即可。
就像nlohmann库的release部分不仅支持源码的下载,也支持项目集成所需的include文件夹。如下图
集成到项目中可以直接下载include文件夹,并复制到项目所在的文件夹,通过MSVC指定附加包含目录或者使用cmake指定inlclude_directories后,便可在项目中使用nlohmann。
代码示例
待生成和解析的json字符串如下
代码语言:javascript复制{
"address" :
{
"city" : "Beijing",
"country" : "China"
},
"age" : 30,
"is_student" : false,
"name" : "夏利",
"subjects" :
[
{
"name" : "Chinese",
"score" : 89
},
{
"name" : "English",
"score" : 72
},
{
"name" : "Math",
"score" : 68
}
]
}
生成json字符串
代码语言:javascript复制#include"nlohmann/json.hpp"
usingnamespacenlohmann;
constexprint subject_num = 3;
std::string subject_name[subject_num] = { "Chinese","English","Math" };
intsubject_score[subject_num] = { 89,72,68 };
void using_write()
{
json j;
j["age"] = 30;
j["is_student"] = false;
j["name"]="danny";
//封装对象方式1
//j["address"]["city"]="beijing";
//j["address"]["country"] = "China";
//封装对象方式2
j["address"]={{"city","beijing"},{"country","China"}};
for (size_t i = 0; i < subject_num; i )
{
//封装数组方式1
//json array_item;
//array_item["name"] = subject_name[i];
//array_item["score"] = subject_score[i];
//j["subjects"].emplace_back(array_item);
//封装数组方式二
// j["subjects"][i]["name"] = subject_name[i];
//j["subjects"][i]["score"] = subject_score[i];
}
//封装数组方式三,标准容器
std::map<std::string, int>name_score = { {"Chinese",89},{"English",72},{"Math",68} };
json sub(name_score);
j["subjects"]=sub;
auto json_result = j.dump();
std::cout<<json_result;
}
由以上可知:
- 该库封装对象更加方便,形式上趋近于二维数组;
- 该库对于数组类型的封装更加方便,既可以像传统的方式,将数组中的元素视为item(参见方式一),也可以将元素直接以不同的下标形式追加到数组内,趋向于C 中容器的概念,通过[i]为其赋值(参见方式二),也可将数组内元素使用标准容器vector、list、array、dequeue、set或map、multimap等,直接构造json对象(参见方式三)
解析json字符串
代码语言:javascript复制void using_read()
{
const std::string json_data = std::string(
"{ "address" :
{
"city" : "Beijing",
"country" : "China"
},
"age" : 30,
"is_student" : false,
"name" : "danney",
"subjects" :
[
{
"name" : "Chinese",
"score" : 89
},
{
"name" : "English",
"score" : 72
},
{
"name" : "Math",
"score" : 68
}
]
}");
auto j = json::parse(json_data);
//隐式类型转换
std::string name = j.at("name");
//显示类型转换
int age = j.at("age").get<int>();
bool is_student;
j.at("is_student").get_to(is_student);
//解析对象
auto city = j.at("address").at("city");
auto country=j.at("address").at("country");
//解析数组
auto subjects = j.at("subjects");
for (constauto& sub:subjects)
{
std::string name = sub.at("name");
float score = sub.at("score");
std::cout<<name<<"t"<<score<<"n";
}
}
由以上可知
- 该库对于对象的解析更加便捷,使用at().at()即可。
- 该库在解析值时,可以使用隐式类型转换和显示类型转换,并且该库推荐使用显示类型转换,显示类型转换支持两种方式,一种使用模板函数get<>,一种使用get_to函数。
总结
nlohmann对于现代C 的支持度非常高,解析和生成json都很方便。但是其并不是紧凑型格式,存在占用空间大的问题,为此,其提供了多种将json对象转换成字节流的方法,在此不再赘述。
参考:
https://github.com/nlohmann/json?tab=readme-ov-file#serialization--deserialization