jsoncpp 是一个c++库,用于解析和生成json数据。它支持解析json文件或字符串到c++对象,以及将c++对象序列化回json格式。
安装jsoncpp
我们可以输入以下命令安装jsoncpp库。
sudo yum install -y jsoncpp-devel
安装时默认安装动态库。头文件存储在 /usr/include/jsoncpp/json 中。
库文件存储在 /lib64 中,我们可以简单查看一下。
jsoncpp的使用
对于 jsoncpp 我们只需要掌握三个类就可以覆盖开发时的绝大多数场景。
- json::value:
- 这是 jsoncpp 中最核心的类,用于表示 json 值。json::value 可以包含任何 json 类型的数据:对象(一组键值对)、数组、字符串、数字、布尔值(true/false)、null 值。你可以使用这个类来创建、查询和修改 json 数据。
- json::reader:
- json::reader 类用于解析 json 字符串。你可以使用这个类将一个符合 json 格式的字符串解析成一个 json::value 对象。这个过程称为 json 反序列化。
- json::writer:
- json::writer 类用于将 json::value 对象转换回 json 字符串。这个过程称为 json 序列化。json::writer 还可以格式化 json 数据,使其以易于阅读的方式输出。
jsoncpp库中的类定义在命名空间 json 中 ,在使用时我们需要声明命名空间。
json 支持以下类型:
nullvalue | 空值 |
intvalue | 有符号整数 |
uintvalue | 无符号整数 |
realvalue | 浮点数 |
stringvalue | 字符串 |
booleanvalue | 布尔数 |
arrayvalue | 数组 |
objectvalue | 键值对 |
value类
value 类是数据的容器,它支持存储json中的所有类型。value为我们提供了各种类型的构造函数。
构造函数
默认构造函数:
json::value value; //创建一个空的value对象
构造一个具有特定类型的值:
json::value value(1); // 整数 json::value value(1.0); // 浮点数 json::value value("string"); // 字符串 json::value value(true); // 布尔值
构造一个数组或对象:
json::value array(json::arrayvalue); // 空数组 json::value object(json::objectvalue);// 空对象
复制构造函数:
json::value value1; json::value value2(value1); // value2 是 value1 的副本
构造一个具有特定值的数组或对象:
json::value array(json::arrayvalue); // 明确指定数组类型 json::value object(json::objectvalue); // 明确指定对象类型
构造一个包含初始值的数组或对象:
json::value array(json::arrayvalue, 10); // 创建一个包含10个元素的数组,每个元素都是null json::value object(json::objectvalue, 5); // 创建一个包含5个元素的对象
从另一个 json 值构造:
json::value value1("initial value"); json::value value2 = value1; // value2 是 value1 的副本
jsoncpp也为我们提供了一系列的检测 value 中存储的值。这些接口都很简单,从命名即可看出它们的作用,在此不过多介绍。
检测保存的数据类型
bool isnull() const; bool isbool() const; bool isint() const; bool isint64() const; bool isuint() const; bool isuint64() const; bool isintegral() const; bool isdouble() const; bool isnumeric() const; bool isstring() const; bool isarray() const; bool isobject() const;
当我们从一个 json::value 对象中提取数据时,我们需要将它转换为相应的实际数据类型,同样jsoncpp 为我们提供了相应的接口。
提取数据
// 将 json::value 对象转换为 int 类型。 int asint() const; // 将 json::value 对象转换为 unsigned int 类型。 uint asuint() const; // 将 json::value 对象转换为 int64_t 类型。 int64 asint64() const; // 将 json::value 对象转换为 uint64_t 类型。 uint64 asuint64() const; // 将 json::value 对象转换为最大的整数类型(long long 类型)。 largestint aslargestint() const; // 将 json::value 对象转换为最大的无符号整数类型(unsigned long long 类型)。 largestuint aslargestuint() const; // 将 json::value 对象转换为 std::string 类型。 jsoncpp_string asstring() const; // 将 json::value 对象转换为 float 类型。 float asfloat() const; // 将 json::value 对象转换为 double 类型。 double asdouble() const; // 将 json::value 对象转换为 bool 类型。 bool asbool() const; // 将 json::value 对象转换为 c 风格的字符串(const char* 类型)。 const char* ascstring() const;
在这些接口中,除了 ascstring() 类型不匹配会返回空指针,其他接口在类型不匹配时都会则抛出 json::typeerror。
这些接口都很简单,我们可以简单使用一下。
#include<jsoncpp/json/json.h> #include<iostream> using namespace json; int main() { value a(1234); if(a.isint()) { int b=a.asint(); std::cout << b << std::endl; } return 0; }
因为 jsoncpp 是一个第三方库,所以编译时我们需要使用 -l 指定需要链接的库。
g++ -o test jsontest.cpp -ljsoncpp
可以看到程序按预期输出 1234 。
对于json数组 value 同样有一系列接口。
对json数组的操作
json数组可以存储json支持的所有类型,包括数组。
arrayindex size() const;
返回数组时的大小,即数组中的元素数量。
value& operator[](arrayindex index); value& operator[](int index);
重载的 [] 运算符,用于访问 json::value 对象作为数组时指定索引的元素。返回 json::value 对象的引用,允许修改。
const value& operator[](arrayindex index) const; const value& operator[](int index) const;
重载的 [] 运算符,用于访问 json::value 对象作为数组时指定索引的元素。返回 json::value 对象的常量引用,不允许修改。
value get(arrayindex index, const value& defaultvalue) const;
使用指定的 index 下标访问 json::value 对象中的元素。如果 index 在有效范围内,返回对应的 json::value 对象。如果 index 无效,返回提供的 defaultvalue。
value& append(const value& value);
向数组的末尾添加一个新元素,并返回对新元素的引用。
const_iterator begin() const;
返回一个迭代器,指向 json::value 对象作为数组或对象的第一个元素。这个迭代器是 const_iterator 类型,只能用于读取元素。
const_iterator end() const;
返回一个迭代器,指向 json::value 对象数组或对象末尾的下一个位置。这个迭代器是 const_iterator 类型,表示迭代结束的位置。
#include<jsoncpp/json/json.h> #include<iostream> using namespace json; int main() { value arr(arrayvalue); value a(1); value b("hello world"); arr.append(a); arr.append(b); int x=arr[0].asint(); const char* y=arr[1].ascstring(); std::cout << "arr[0]:" << x << std::endl; std::cout << "arr[1]:" << y << std::endl; return 0; }
iterator begin();
返回一个迭代器,指向 json::value 对象作为数组或对象的第一个元素。这个迭代器是 iterator 类型,允许修改元素。
iterator end();
返回一个迭代器,指向 json::value 对象数组或对象末尾的下一个位置。这个迭代器是 iterator 类型,表示迭代结束的位置。
我们简单使用一下:
#include<jsoncpp/json/json.h> #include<iostream> using namespace json; int main() { value arr(arrayvalue); value a(1); value b("hello world"); arr.append(a); arr.append(b); int x=arr[0].asint(); const char* y=arr[1].ascstring(); std::cout << "arr[0]:" << x << std::endl; std::cout << "arr[1]:" << y << std::endl; return 0; }
运行结果:
对json对象的操作
json 对象由一系列键值对组成,其中每个键都是一个字符串,与一个值关联。json 对象的键值对是无序的,这意味着键值对的顺序可能会在不同的 json 对象中有所不同,但它们表示相同的数据。同时json 对象中的每个键都是唯一的,不允许有重复的键。
添加键值对:
obj["key1"] = "value1"; // 使用操作符 [] 添加键值对 obj["key2"] = 123; // 键可以关联不同类型的值
访问值:
json::value value = obj["key1"]; // 获取键 "key1" 对应的值
检查键是否存在:
if (obj.ismember("key1")) // 键 "key1" 存在
获取所有键的名称:
json::value::members members = obj.getmembernames(); for (const auto& key : members) { std::cout << key << std::endl; }
members是std::vector<std::string>的typedef别名。
修改值:
obj["key1"] = "new value"; // 修改已存在的键 "key1" 对应的值
删除键值对:
obj.removemember("key1"); // 删除键 "key1" 及其对应的值
检查 json 对象是否为空:
bool isempty = obj.empty();
获取 json 对象的大小
json::arrayindex size = obj.size(); // 返回对象中键值对的数量
我们简单演示一下使用。
#include<jsoncpp/json/json.h> #include<iostream> using namespace json; int main() { value obj(json::objectvalue); obj["age"]=18; obj["name"]="张三"; json::value::members members = obj.getmembernames(); for (const auto& key : members) { std::cout << key << std::endl; } for (const auto &e : members) { std::cout << e << ":" << obj[e] << std::endl; } return 0; }
我们运行一下。
value也为我们提供了接口将对象序列化。
std::string tostyledstring() const;
这个接口序列化出的字符串是带缩进与换行的,我们简单演示一下。
#include<jsoncpp/json/json.h> #include<iostream> #include<string> using namespace json; int main() { value obj(json::objectvalue); obj["age"]=18; obj["name"]="张三"; std::string s = obj.tostyledstring(); std::cout << s << std::endl; return 0; }
运行结果
fastwriter类
在 jsoncpp 中,fastwriter可以将 json::value 对象转换为 json 格式的字符串。与styledstreamwriter 不同,fastwriter 不进行任何美化(不添加空格和缩进),因此通常会产生更紧凑的输出,但写入速度更快。在网络通信中,我们通常用它将数据序列化为单行,便于进行网络数据的传输。
std::string json::fastwriter::write(const value& root);
我们只需要掌握这一个接口即可,它会将传入的对象序列化为单行的字符串。
我们简单使用一下。
#include<jsoncpp/json/json.h> #include<iostream> #include<string> using namespace json; int main() { value obj(json::objectvalue); obj["age"]=18; obj["name"]="张三"; fastwriter writer; std::string s=writer.write(obj); std::cout << s ; return 0; }
运行结果:
reader类
有序列化,就有反序列化,在将json对象进行序列化后,我们可以通过 read 类进行反序列化,
bool json::reader::parse(const std::string& document,value& root, bool collectcomments = true);
参数:
- document: json格式字符串
- root: 传出参数, 存储了json字符串中解析出的数据
- collectcomments: 是否保存json字符串中的注释信息默认true
parse有其他重载,但在这里我们不过多介绍。这里我们简单演示一下parse的使用
#include<jsoncpp/json/json.h> #include<iostream> #include<string> using namespace json; int main() { value obj(json::objectvalue); obj["age"]=18; obj["name"]="张三"; fastwriter writer; std::string s=writer.write(obj); std::cout << s ; reader reader; value val; reader.parse(s,val); std::cout << val["age"] << std::endl; std::cout << val["name"] << std::endl; return 0; }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论