轻量版C++json库,支持自定义类型
这是一个轻量级的C++ JSON序列化/反序列化库,支持基本数据类型和自定义容器类型。主要功能包括:序列化对象为JSON字符串(支持美化输出)、反序列化JSON为指定对象、提供自定义类型扩展接口。内置增强型容器类(Str/List/Dict),支持嵌套结构和混合类型操作。使用C++20标准,需手动实现原生容器的序列化方法。项目开源,通过头文件即可集成,适合现代C++项目快速处理JSON数据。
文章目录
项目名称
该项目是我在学习现代c++编程时所写的一个用于序列化对象为json和反序列化json为指定对象的c++库。该库的特点就是轻量,便捷,灵活。
功能特性
- 功能 1:序列化基本数据类型(
nullptr_t
、bool
、整数
、double
)、内定类型(Str
、Dict
和List
)为json,支持json美化。 - 功能 2:反序列化json文本为指定对象。
- 功能 3:提供支持有限的自定义类型序列化和反序列化接口,需要自己去实现这两个方法。
注意:默认并不支持 c + + 原生容器的序列化合反序列化,需要自己实现这两个方法。 \textcolor{BrickRed}{注意:默认并不支持c++原生容器的序列化合反序列化,需要自己实现这两个方法。} 注意:默认并不支持c++原生容器的序列化合反序列化,需要自己实现这两个方法。
安装指南
# 克隆项目
git clone https://github.com/LonelyWindy/cjson.git
然后将cjson.h和file_view.h放到你的项目中。
注意:请使用 C + + 20 及以上标准! \textcolor{BrickRed}{注意:请使用C++20及以上标准!} 注意:请使用C++20及以上标准!
内定数据类型
Str
增强的std::string
,使用方法在原来的基础上,新增格式化字符串方法 f o r m a t \textcolor{cornflowerblue}{format} format:
auto str = cjson::Str();
str.format("%s %d %.2f\n", "cvk", 18, 168.5);
std::cout << str << std::endl;
// cvk 18 168.50
List
增强的std::vector
,可以存储任何类型的元素,并支持任何元素的查找和比较:
auto l = cjson::List("Cxk", 18, 168.5, -894, true, nullptr);
auto d = cjson::Dict();
d["48"] = 1564;
d[-8] = "5ef46";
l.append(d);
std::cout << l <<std::endl;
std::cout<< l.index(true) << std::endl;
std::cout<< l.index(d) << std::endl;
// ["Cxk",18,168.500000,-894,true,null]
// 4
Dict
增强的std::map
,可以存储任何类型的元素,并支持任何元素的查找和比较:
auto d = cjson::Dict();
d[15] = "xdwdf";
auto l = cjson::List("fewf",84,-4);
d[-59] = l;
d["ef"] = cjson::Dict();
d["ef"].as_dict()["878"] = -5486;
d["ef"].as_dict()[0.15415] = "ewfeewf";
std::cout << d <<std::endl;
// {"-59":["fewf",84,-4],"15":"xdwdf","ef":{"0.154150":"ewfeewf","878":-5486}}
接口
序列化为json字符串
std::string dumps(
const std::any& object,
int indent = 0
)
- object,任意对象,如果是自己定义对象需要自己实现序列化合反序列化方法。
- indent,json字符串缩进,默认为0,表示不美化。常用值2和4。
反序列化json字符串为对象
JValue loads(
file_view::StreamView&& json,
size_t* end_pos = nullptr
);
-
json,json字符串或者json文件路径。如果需要传入json文件路径需要显示调用StreamView的构造函数,并指定file_mode参数为true。
-
end_pos,反序列化结束位置,json字符串中的下标或者json文件偏移。可空。
注册自己的序列化和反序列化方法
using ObjDumper = std::function<std::string(const std::any& obj, int indent, int current_indent, bool first)>;
using JInterpreter = std::function <JValue(file_view::StreamView& json, size_t current_pos, size_t& end_pos)>;
void register_json_interpreter(
ObjDumper dumper,
JInterpreter interpreter
);
- dumper,将对象序列化为json字符串的方法。
- interpreter,将json字符串反序列化为对象的方法。
例子
List的序列化和反序列化
auto l = cjson::List("fesd", 156, -8879, true, -748.4854, 'F');
auto json = cjson::dumps(l,4);
std::cout << json << std::endl;
auto new_l = cjson::loads(json);
std::cout << new_l.as_list() << std::endl;
输出:
[
"fesd",
156,
-8879,
true,
-748.485400,
70
]
["fesd",156,-8879,true,-748.485400,70]
Dict的序列化和反序列化
auto d = cjson::Dict();
d["fe"] = "defr5y5";
d["45t45"] = 156;
d[454] = -156056;
d[-54] = 545.07;
auto json = cjson::dumps(d,4);
std::cout << json << std::endl;
auto new_d = cjson::loads(json);
std::cout << new_d.as_dict() << std::endl;
输出:
{
"fe": "defr5y5",
"45t45": 156,
"454": -156056,
"-54": 545.070000
}
{"fe":"defr5y5","45t45":156,"454":-156056,"-54":545.070000}
嵌套List序列化和反序列化
auto l1 = cjson::List("fesd", 156, -8879, false, -748.4854, 'F');
auto l2 = cjson::List("{fesd}", "s\ta44\r5\a5y\n", -56.454, 0x45489, nullptr, 'F4t\t');
auto l3 = cjson::List();
l3.append(l1);
l3.append("dt4t");
l3.append(l2);
l3.append(cjson::List());
auto json = cjson::dumps(l3,4);
std::cout << json << std::endl;
auto new_d = cjson::loads(json);
std::cout << new_d.as_list() << std::endl;
输出:
[
[
"fesd",
156,
-8879,
false,
-748.485400,
70
],
"dt4t",
[
"{fesd}",
"s\ta44\r5\u00075y\n",
-56.454000,
283785,
null,
1177842697
],
[]
]
[["fesd",156,-8879,false,-748.485400,70],"dt4t",["{fesd}","s\ta44\r5\u00075y\n",-56.454000,283785,null,1177842697],[]]
嵌套Dict序列化和反序列化
auto d = cjson::Dict();
d["fe"] = "defr5y5";
d["45t45"] = 156;
d[454] = -156056;
d[-54] = cjson::Dict();
d[55] = cjson::Dict();
d[55].as_dict()[56] = "efgerg";
d[55].as_dict()[-56] = 0.41564;
d[55].as_dict()[0.415] = -464;
auto d2 = cjson::Dict();
d2["5tg\r"] = "{g5y\t6}";
d2[0.458] = 548.154;
d["\n"] = d2;
auto json = cjson::dumps(d,4);
std::cout << json << std::endl;
auto new_d = cjson::loads(json);
std::cout << new_d.as_dict() << std::endl;
输出:
{
"fe": "defr5y5",
"\n": {
"5tg\r": "{g5y\t6}",
"0.458000": 548.154000
},
"45t45": 156,
"454": -156056,
"-54": {},
"55": {
"56": "efgerg",
"-56": 0.415640,
"0.415000": -464
}
}
{"fe":"defr5y5","45t45":156,"\n":{"5tg\r":"{g5y\t6}","0.458000":548.154000},"454":-156056,"-54":{},"55":{"56":"efgerg","-56":0.415640,"0.415000":-464}}
List和Dict混合序列化和反序列化1
auto d = cjson::Dict();
auto l2 = cjson::List("{fesd}", "s\ta44\r5\a5y\n", -56.454, 0x45489, nullptr, 'F4t\t', false, true);
d.insert(45, l2);
auto l1 = cjson::List("fesd", 156, -8879, false, -748.4854, 'F');
l1.append(d);
auto json = cjson::dumps(l1, 4);
std::cout << json << std::endl;
auto new_d = cjson::loads(json);
std::cout << new_d.as_list() << std::endl;
输出:
[
"fesd",
156,
-8879,
false,
-748.485400,
70,
{
"45": [
"{fesd}",
"s\ta44\r5\u00075y\n",
-56.454000,
283785,
null,
1177842697,
false,
true
]
}
]
["fesd",156,-8879,false,-748.485400,70,{"45":["{fesd}","s\ta44\r5\u00075y\n",-56.454000,283785,null,1177842697,false,true]}]
List和Dict混合序列化和反序列化2
auto d = cjson::Dict();
auto l2 = cjson::List("{fesd}", "s\ta44\r5\a5y\n", -56.454, 0x45489, nullptr, 'F4t\t', false, true);
d.insert(45, l2);
auto l1 = cjson::List("fesd", 156, -8879, false, -748.4854, 'F');
l1.append(d);
d[87.15] = l1;
auto json = cjson::dumps(d, 4);
std::cout << json << std::endl;
auto new_d = cjson::loads(json);
std::cout << new_d.as_dict() << std::endl;
输出:
{
"45": [
"{fesd}",
"s\ta44\r5\u00075y\n",
-56.454000,
283785,
null,
1177842697,
false,
true
],
"87.150000": [
"fesd",
156,
-8879,
false,
-748.485400,
70,
{
"45": [
"{fesd}",
"s\ta44\r5\u00075y\n",
-56.454000,
283785,
null,
1177842697,
false,
true
]
}
]
}
{"45":["{fesd}","s\ta44\r5\u00075y\n",-56.454000,283785,null,1177842697,false,true],"87.150000":["fesd",156,-8879,false,-748.485400,70,{"45":["{fesd}","s\ta44\r5\u00075y\n",-56.454000,283785,null,1177842697,false,true]}]}
自定义类型序列化和反序列化
class Custom
{
private:
int32_t age_ = 0;
bool female_ = false;
std::string name_;
cjson::List likes_;
public:
Custom() = default;
Custom(int32_t age, bool female, const std::string& name, const cjson::List& likes)
: age_(age)
, female_(female)
, name_(name)
, likes_(likes)
{ }
int32_t get_age() const { return age_; }
bool get_gender() const { return female_; }
const std::string& get_name() const { return name_; }
const cjson::List& get_likes() const { return likes_; }
void set_age(const int32_t age) { age_ = age; }
void set_gender(const bool female) { female_ = female; }
void set_name(const std::string& name) { name_ = name; }
void set_likes(const cjson::List& likes) { likes_ = likes; }
};
void test_custom()
{
Custom c(32, false, "Cxk", { "Sing","Dump","Rap" });
auto json = cjson::dumps(c, 4);
std::cout << json << std::endl;
auto obj = cjson::loads(json);
if (obj.any_value_.type() == typeid(Custom))
{
std::cout << "Suc\n";
std::cout << cjson::dumps(obj.as_other<Custom>(), 4) << std::endl;
}
else
{
std::cout << "Fail\n";
}
}
int main()
{
cjson::register_json_interpreter<Custom>(dump_custom, load_custom);
test_custom();
}
输出:
<
age: 32,
gender: male,
name: Cxk,
likes: [
"Sing",
"Dump",
"Rap"
]
>
Suc
<
age: 32,
gender: male,
name: Cxk,
likes: [
"Sing",
"Dump",
"Rap"
]
>
贡献指南
欢迎提交 Issue !
许可证
本项目采用GPL-3.0 license许可证。
更多推荐
所有评论(0)