C++基于jsoncpp开源库json数据操作

C++基于jsoncpp开源库json数据操作

简述

json官网

jsoncpp源码下载

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;
}
相关推荐
艾莉丝努力练剑35 分钟前
【Linux基础开发工具 (五)】详解自动化构建:make / Makefile
linux·运维·服务器·c++·centos·自动化
Predestination王瀞潞38 分钟前
安装了Anaconda在系统终端却无法使用python命令
linux·开发语言·python
艾莉丝努力练剑3 小时前
【C++:异常】C++ 异常处理完全指南:从理论到实践,深入理解栈展开与最佳实践
java·开发语言·c++·安全·c++11
快乐zbc9 小时前
【C++ 基础】:给定一个指针 p,你能判断它是否指向合法的对象吗?
c++
岁忧9 小时前
GoLang五种字符串拼接方式详解
开发语言·爬虫·golang
tyatyatya9 小时前
MATLAB基础数据类型教程:数值型/字符型/逻辑型/结构体/元胞数组全解析
开发语言·matlab
sulikey9 小时前
C++类和对象(下):初始化列表、static、友元、内部类等核心特性详解
c++·static·初始化列表·友元·匿名对象·内部类·编译器优化
心无旁骛~10 小时前
python多进程和多线程问题
开发语言·python
星云数灵10 小时前
使用Anaconda管理Python环境:安装与验证Pandas、NumPy、Matplotlib
开发语言·python·数据分析·pandas·教程·环境配置·anaconda