json 格式作为一种较为通用的数据存储格式 ,在实际应用中使用的非常频繁。直接操作对应的 json 文件又是一个耗时耗力的过程 ,可以使用其他大佬写的轮子 ,使用开源库方便我们操作 json 文件;
在C++ 中使用json 可以使用一个开源库 jsoncpp
,使用前需要在GitHub 下载对应源文件,然后编译成动态库,随后在自己的项目中引入使用;
如果觉得麻烦可以下载我个人编译好的库文件 ,我自己为了以后可以方便使用放置在C 盘;
然后看
VS项目案例
百度网盘链接:https://pan.baidu.com/s/1H3Tm2Xkh1RqNud2JYyHDjw
提取码:1234
下载内容 : jsoncpp 、 cmake 、 Visual Studio 2022 (个人IDE)
Jsoncpp 是个跨平台的 C++ 开源库,提供的类为我们提供了很便捷的操作,而且使用的人也很多。在使用之前我们首先要从 github 仓库下载源码,地址如下:
https://github.com/open-source-parsers/jsoncpp
方式一 : 使用git工具下载;
方式二: 直接下载项目压缩包;
于 C++ 程序猿都是基于 VS 进行项目开发,下载的源码我们一般不会直接使用,而且将其编译成相应的库文件(动态库或者静态库),这样不论是从使用或者部署的角度来说,操作起来都会更方便一些;
但是 ,直接在github 下载的源码不能直接在 VS 中打开,我们需要现在 cmake工具将下载的项目构建成一个 VS 项目 ,随后使用 VS 编译出需要的 库文件;
CMake 下载地址:
https://cmake.org/download/
安装过程基本上全程点击 下一步 ,不在此多说,怕出错的朋友可以自行百度如何安装cmake。
随后使用 VS 找到输出目录
中的 .sln 文件打开;
新建一个文件夹 jsoncpp,存放库文件和对应头文件
将从github下载源文件夹中 include 文件夹
拷贝到 jsoncpp文件夹中
jsoncpp 中新建库文件夹lib 将刚才cmake输出文件夹中 lib/Debug/jsoncpp.lib
bin/Debug/jsoncpp.dll 放入该文件夹
jsoncpp库中的类定义在 名为 Json 的命令空间
,为了方便使用,使用库前先声明该命名空间
using namespace Json;
使用 jsoncpp 库解析 json 格式的数据,我们只需要掌握三个类:
==Value 类:==将 json 支持的数据类型进行了包装,最终得到一个 Value 类型;
==FastWriter类:==将 Value 对象中的数据序列化为字符串;
==Reader类:==反序列化,将 json 字符串 解析成 Value 类型;
具体成员函数须有需要请留言 ,或者自行百度;
为了方便之后使用 jsoncpp 库 ,我将该编译完成的自建文件夹(包含include \lib) 放置在C 盘方便以后使用,各位程序猿可以根据自己的需求合理存放该动态库;
在vs中新建一个空项目并更改项目属性
1、改包含目录
2、改 库目录
3、还需要告诉 VS 需要加载的动态库是哪一个
此处指定的是==动态库对应的 lib 文件,==也就是 jsoncpp.lib
配置完成之后,如果项目中使用了 jsoncpp 就可以编译通过了。在程序执行的时候,如果提示找不到 jsoncpp 的动态库,
别忘记了把 jsoncpp.dll 拷贝到可执行所在的目录下就可以解决这个问题了。
假设对如下json数组操作
[
12,
12.34,
true,
"tom",
["jack", "ace", "robin"],
{"sex":"man", "girlfriend":"lucy"}
]
代码示例:
#include
#include // IO 操作
#include
using namespace std;
using namespace Json;
// 写 json文件
void writeJson()
{
// 将最外层的数组看做一个Value
// 最外层的Value对象创建
Value root;
// Value有一个参数为int 行的构造函数
root.append(12); // 参数进行隐式类型转换
root.append(12.34);
root.append(true);
root.append("tom");
// 创建并初始化一个子数组
Value subArray;
subArray.append("jack");
subArray.append("ace");
subArray.append("robin");
root.append(subArray);
// 创建并初始化子对象
Value subObj;
subObj["sex"] = "woman"; // 添加键值对
subObj["girlfriend"] = "lucy";
root.append(subObj);
// 序列化
#if 1
// 有格式的字符串
string str = root.toStyledString();
#else
FastWriter f;
string str = f.write(root);
#endif
// 将序列化的字符串写磁盘文件
ofstream ofs("test.json");
ofs << str;
ofs.close();
}
// 读 json 文件
void readJson()
{
// 1. 将磁盘文件中的json字符串读到磁盘文件
ifstream ifs("test.json");
// 2. 反序列化 -> value对象
Value root;
Reader r;
r.parse(ifs, root);
// 3. 从value对象中将数据依次读出
if (root.isArray())
{
// 数组, 遍历数组
for (int i = 0; i < root.size(); ++i)
{
// 依次取出各个元素, 类型是value类型
Value item = root[i];
// 判断item中存储的数据的类型
if (item.isString())
{
cout << item.asString() << ", ";
}
else if (item.isInt())
{
cout << item.asInt() << ", ";
}
else if (item.isBool())
{
cout << item.asBool() << ", ";
}
else if (item.isDouble())
{
cout << item.asFloat() << ", ";
}
else if (item.isArray())
{
for (int j = 0; j < item.size(); ++j)
{
cout << item[j].asString() << ", ";
}
}
else if (item.isObject())
{
// 对象
// 得到所有的key
Value::Members keys = item.getMemberNames();
for (int k = 0; k < keys.size(); ++k)
{
cout << keys.at(k) << ":" << item[keys[k]] << ", ";
}
}
}
cout << endl;
}
}
int main()
{
writeJson();
readJson();
return 0;
}