C++基于jsoncpp开源库json数据操作
简述
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人类阅读和编写,同时便于机器解析和生成。它基于ECMAScript的子集设计,独立于编程语言,广泛应用于Web开发、API通信、配置文件等领域。
核心特点
- 简洁性:采用键值对结构,支持嵌套对象和数组,语法清晰 。
- 跨平台:被主流编程语言(如Java、Python、JavaScript)原生支持 。
- 传输效率:数据量小,适合网络传输,常用于RESTful API和微服务通信 。
基本结构
-
对象(Object):无序键值对集合,用{}包裹,键为双引号字符串,值可为字符串、数字、布尔值、数组、对象或null 。
-
数组(Array):有序值集合,用[]包裹,元素可为任意类型 。
-
典型应用场景
-
前后端数据交互:如AJAX请求、Spring Boot与前端框架的通信 。
-
配置文件:如NoSQL数据库(MongoDB)的文档存储 。
-
物联网与移动应用:设备状态传输、用户信息存储等 。

主要类和方法
Json::Value 主要方法
- isNull(), isBool(), isInt(), isUInt(), isDouble(), isString(), isArray(), isObject() - 类型检查
- asInt(), asUInt(), asInt64(), asUInt64(), asFloat(), asDouble(), asBool(), asString() - 类型转换
- append(const Value& value) - 向数组添加元素
- size() - 获取数组大小或对象成员数量
- empty() - 检查是否为空
- isMember(const char* key) - 检查对象是否包含指定键
- getMemberNames() - 获取对象的所有键
- operator[](const char* key) - 访问对象成员
- operator[](Json::ArrayIndex index) - 访问数组元素
构建器和读写器
- Json::StreamWriterBuilder - 构建 JSON 序列化器
- Json::CharReaderBuilder - 构建 JSON 解析器
- Json::writeString() - 将 JSON 对象序列化为字符串
- Json::parseFromStream() - 从流中解析 JSON
使用示例
创建简单JSON数据
cpp
Json::Value root;
root["name"] = "syl";
root["age"] = 20;
std::string json_str = root.toStyledString();
std::cout<<json_str<<std::endl;
创建缩进JSON数据
cpp
Json::Value root;
root["name"] = "songyl";
root["age"] = 22;
Json::StreamWriterBuilder builder;
// builder["indentation"] = " "; // 带缩进(默认),生成格式化JSON
builder["indentation"] = ""; // 取消缩进,生成紧凑JSON
std::string json_str = Json::writeString(builder, root);
std::cout<<json_str<<std::endl;
从string解析JSON数据
cpp
std::string json_str = R"({
"name": "syl",
"age": 20,
"gender": "male",
"flag": true,
"score": 90.5
})";
Json::Reader reader;
Json::Value root;
if (false == reader.parse(json_str, root)) {
std::cout<<"parse failed!\n"<<std::endl;
std::cout<<"error: "<<reader.getFormattedErrorMessages()<<std::endl;
} else {
std::cout<<"parse success!\n"<<std::endl;
std::cout<<"name = "<<root["name"].asString()<<std::endl;
std::cout<<"age = "<<root["age"].asInt()<<std::endl;
std::cout<<"gender = "<<root["gender"].asString()<<std::endl;
std::cout<<"flag = "<<root["flag"].asBool()<<std::endl;
std::cout<<"score = "<<root["score"].asFloat()<<std::endl;
}
从文件解析JSON数据
cpp
Json::Value root;
Json::Reader reader;
std::ifstream inFile("test.json");
if (inFile.is_open()) {
if (false == reader.parse(inFile, root)) {
std::cout<<"parse failed!\n"<<std::endl;
std::cout<<"error: "<<reader.getFormattedErrorMessages()<<std::endl;
} else {
std::cout<<"parse success!\n"<<std::endl;
if (root.isMember("TracksMetaData") && root["TracksMetaData"].isArray()) {
Json::Value array = root["TracksMetaData"];
std::cout << "array size:" << array.size() << std::endl;
std::cout<<"root = "<<root.toStyledString()<<std::endl;
}
}
inFile.close();
}
json
删除JSON数组指定索引元素
cpp
/// @brief 删除Json数组中指定索引的元素
/// @param jsonArray Json数组 从1开始索引
/// @param index 要删除的元素索引
/// @return 删除成功返回true,否则返回false
bool removeArrayElementByIndex(Json::Value& jsonArray, size_t index) {
if (!jsonArray.isArray()) {
std::cerr << "错误:输入不是Json数组!" << std::endl;
return false;
}
if (index < 1) {
std::cerr << "错误:索引不能小于1!" << std::endl;
return false;
}
if (index >= jsonArray.size()) {
std::cerr << "错误:索引超出数组范围!" << std::endl;
return false;
}
Json::Value removedElment;
return jsonArray.removeIndex(index-1, &removedElment);
}
删除JSON数组指定索引范围元素
cpp
/// @brief 删除Json数组中指定索引范围的元素
/// @param jsonArray Json数组 从1开始索引
/// @param startIndex 开始索引 从1开始索引
/// @param numberOfArray 要删除的元素数量 ,最小删除1个元素
/// @return 删除成功的元素数量,失败返回负数
int removeArrayElementByRange(Json::Value& jsonArray, size_t startIndex, size_t numberOfArray) {
if (!jsonArray.isArray()) {
std::cout << "错误:输入不是Json数组!" << std::endl;
return -1;
}
if (startIndex < 1) {
std::cout << "错误:开始索引不能小于1!" << std::endl;
return -2;
}
if (numberOfArray < 1) {
std::cout << "错误:移除个数不能小于1!" << std::endl;
return -3;
}
if ((startIndex > jsonArray.size()) || ((startIndex + numberOfArray)-1 > jsonArray.size())) {
std::cout << "错误:索引超出数组范围!" << std::endl;
return -4;
}
int removedCnt = 0;
Json::Value removedElement;
for (size_t i = (startIndex + numberOfArray)-1; i > startIndex-1; --i) {
// std::cout<<"remove i:"<<i-1<<std::endl;
if (jsonArray.removeIndex(i-1, &removedElement) == false) {
return removedCnt;
}
removedCnt += 1; // 成功删除一个元素
}
return removedCnt;
}
查询JSON数组指定索引范围
cpp
/// @brief 查询Json数组中指定索引范围的元素
/// @param jsonArray Json数组 从1开始索引
/// @param newArray 查询到的元素新数组 从1开始索引
/// @param startIndex 开始索引 从1开始索引
/// @param numberOfArray 要查询的元素数量 ,最小查询1个元素
/// @return 查询成功的元素数量,失败返回0
int queryArrayElementByRange(Json::Value& jsonArray, Json::Value& newArray, Json::ArrayIndex startIndex, int numberOfArray)
{
if (!jsonArray.isArray() || !newArray.isArray()) {
std::cout << "错误:输入不是Json数组!" << std::endl;
return -1;
}
if (startIndex < 1) {
std::cout << "错误:开始索引不能小于1!" << std::endl;
return -2;
}
if (numberOfArray < 1) {
std::cout << "错误:移除个数不能小于1!" << std::endl;
return -3;
}
if ((startIndex > jsonArray.size()) || ((startIndex + numberOfArray)-1 > jsonArray.size())) {
std::cout << "错误:索引超出数组范围!" << std::endl;
return -4;
}
int i=0;
for (i=0; i<numberOfArray; i++) {
int index = startIndex + i - 1;
newArray[i] = jsonArray[index];
}
return i;
}