json for modern c++(nlohmann json)使用小计
前言
一开始使用jsoncpp,但是jsoncpp已经不更新了,nlohmann还在更新,并且jsoncpp做过一次大的版本升级,导致api不兼容,以前使用过的工程代码不能很好的升级到新的版本,并且jsoncpp是多个文件支持,使用的时候我编译成了lib,nlohmann是一个头文件,更方便。
nlohmann使用c++11的新功能,更多的c++方法,使用起来更方便。并且nlohmann在调试的时候,可以看到数据结构,这个太有用了,而jsoncpp,只能通过内部的方法导出string。
由于各种原因把jsoncpp切换到nlohmann,在nlohmann使用时有一些需要注意的。不过大部分注意事项作者已经写到github上了 https://github.com/nlohmann/json
1.
nlohmann支持隐式转换,但是不要使用,因为行为不确定
看下面的例子及输出结果
long long lnum = 327221437;
nlohmann::json a;
a["num1"] = 327220625;
nlohmann::json b;
b["num2"] = 900000;
if (lnum - a["num1"] > b["num2"])
{
cout << lnum << endl;
cout << a["num1"] << endl;
cout << b["num2"] << endl;
cout << lnum - a["num1"] << endl;
cout << lnum - a["num1"].get<long long>() << endl;
}
327221437
327220625
900000
327221292
812
lnum - a["num1"] > b["num2"]
并不成立,但是进来了,如果写成lnum - a["num1"].get<long long>() > b["num2"].get<long long>()
就没问题
2.
在调用json::parse(iter.begin(), iter.end())
的时候需要注意,作者也说了,是[iter.begin(), iter.end()),左闭右开的,所以如果是一个数组保存了json字符串,那么就是a, a+len,而不是a, a+len-1
3.
nlohmann::json::parse
如果是非法的json会直接丢一个异常,可以通过nlohmann::json::accept
判断是否合法
4.
error: invalid conversion from ‘nlohmann::json_abi_v3_11_2::detail::iter_impl<const nlohmann::json_abi_v3_11_2::basic_json<> >::pointer’ {aka ‘const nlohmann::json_abi_v3_11_2::basic_json<>*’} to ‘nlohmann::json_abi_v3_11_2::detail::iter_impl<nlohmann::json_abi_v3_11_2::basic_json<> >::pointer’ {aka ‘nlohmann::json_abi_v3_11_2::basic_json<>*’} [-fpermissive]
: m_object(other.m_object), m_it(other.m_it)
这个报错是因为对const nlohmann::json
使用了nlohmann::json::iterator
遍历,类型不匹配,要么删除前面的const,要么修改后面迭代器为const
类型
5.
terminate called after throwing an instance of 'nlohmann::json_abi_v3_11_2::detail::parse_error'
what(): [json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal
这是因为使用了ifstream
后,没有设置文件位置到开头,再次读取文件的时候,从末尾读取的,读取到结束符,不是json内容,报错。最常见的就是如下:
nlohmann::json b;
ifstream ifs;
ifs.open("../text.json");
if (ifs.is_open())
{
if (nlohmann::json::accept(ifs))
{
b = nlohmann::json::parse(ifs);
cout << b << endl;
}
}
先判断文件是否合法,然后再解析,但是当使用accetp
后,ifs
指向了文件末尾,因为已经使用过,读取了文件的内容,文件指针移动到末尾,所以在使用parse
的时候报错了,需要调用ifs.seekg(0);
跳到开头后,再调用parse
进行解析。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!