【学习笔记】nlohmannjson&&cjson

【学习笔记】nlohmann::json&&cjson

json 复制代码
[
    {

       "nodeId":1,
       "refreshRate": 6000,

        "brightness":
        {
                "B": 50, 
                "G": 50, 
                "R": 50,
                "all": 50
         }
    }
]

将上面的数据分别使用nlohmann::json或者cjson实现出来。

一、cjson

c++ 复制代码
#include "cJSON.h"
#include <iostream>
#include <string>

int main() {
    // 创建JSON数组  //root: [ ]
    cJSON* root = cJSON_CreateArray();
    
    // 创建第一个节点对象 node: { }
    cJSON* node = cJSON_CreateObject();
    cJSON_AddNumberToObject(node, "nodeId", 1);
    cJSON_AddNumberToObject(node, "refreshRate", 6000);
    
    // 创建亮度对象brightness: { }
    cJSON* brightness = cJSON_CreateObject();
    cJSON_AddNumberToObject(brightness, "B", 50);
    cJSON_AddNumberToObject(brightness, "G", 50);
    cJSON_AddNumberToObject(brightness, "R", 50);
    cJSON_AddNumberToObject(brightness, "all", 50);
    
    // 将亮度对象添加到节点
    cJSON_AddItemToObject(node, "brightness", brightness);
    
    // 将节点添加到数组
    cJSON_AddItemToArray(root, node);
    
    // 转换为格式化的JSON字符串
    char* jsonString = cJSON_Print(root);
    if (jsonString) {
        std::cout << jsonString << std::endl;
        free(jsonString);  // 释放由cJSON_Print分配的内存
    }
    
    // 释放JSON结构占用的内存
    cJSON_Delete(root);
    
    return 0;
}

​ ● 单文件实现:仅包含 cJSON.c 和 cJSON.h,无需额外依赖,适合嵌入式系统或资源受限环境。

​ ● C 语言兼容性:纯 C 实现,可无缝集成到 C 或 C++ 项目中,不依赖 C++ 标准库。

​ ● 精简的内存模型:采用链表结构存储 JSON 节点,内存占用小,解析速度快(尤其适合小到中型 JSON)。

​ ● 无 STL 依赖:避免了 C++ 标准库的开销,在低性能设备上表现更优。

​ ● 函数式接口:通过 cJSON_Create*、cJSON_Add* 等函数操作 JSON,学习成本低。

​ ● 手动内存管理:允许精细控制内存分配,适合对内存使用敏感的场景。需要手动释放。

二、nlohmann/json

1、nlohmann/json(嵌套赋值)

c++ 复制代码
#include <iostream>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

int main() {
    // 创建空的JSON对象
    json layer_json;

    // 直接使用嵌套赋值(自动创建中间对象)
    layer_json["brightness"]["B"] = 50;
    layer_json["brightness"]["G"] = 50;
    layer_json["brightness"]["R"] = 50;
    layer_json["brightness"]["all"] = 50;

    // 添加其他字段
    layer_json["nodeId"] = 1;
    layer_json["refreshRate"] = 6000;

    // 输出JSON(格式化,缩进4空格)
    std::cout << layer_json.dump(4) << std::endl;

    return 0;
}

2、nlohmann/json(初始化列表)

c++ 复制代码
#include <iostream>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

int main() {
    // 创建JSON数组
    json jsonArray = json::array();

    // 创建第一个节点对象
    json node = {
        {"nodeId", 1},
        {"refreshRate", 6000},
        {"brightness", {
            {"B", 50},
            {"G", 50},
            {"R", 50},
            {"all", 50}
        }}
    };

    // 将节点添加到数组
    jsonArray.push_back(node);

    // 输出JSON(格式化,缩进4空格)
    std::cout << jsonArray.dump(4) << std::endl;

    return 0;
}

3、初始化列表/嵌套赋值差异

​ ● 嵌套赋值:像 "积木",适合逐步组装动态结构。

​ ● 初始化列表:像 "蓝图",适合一次性构建静态结构。

维度 初始化列表方式 嵌套赋值方式
实现机制 一次性构造完整 JSON 结构 动态创建并修改 JSON 结构
适用场景 静态已知的 JSON 结构(编译时确定) 动态生成或修改的 JSON(运行时确定)
代码风格 声明式(类似 JSON 字面量) 命令式(类似 JavaScript 对象操作)
性能 通常略高效(一次性分配内存) 可能多次内存分配(动态扩展)
错误处理 编译时类型检查(如 nodeId 必须为数值) 运行时可能抛出异常
缺点 灵活性低:必须预先知道完整结构,无法动态调整。嵌套层级过深时可读性下降:多层嵌套会导致代码冗长。 潜在性能开销:每次访问不存在的键时会自动创建对象,可能触发多次内存分配。运行时错误风险:若键名拼写错误,会创建新字段而非报错(如 layer_json["brightnes"]["B"])。
性能对比 运行时分配内存:分配内存 → 一次性构造所有节点 → 完成 运行时分配内存:访问 layer_json → 检查 "brightness" 是否存在 → 不存在则创建对象访问 "brightness" → 检查 "B" 是否存在 → 不存在则创建并赋值重复上述步骤...

4、nlohmann优势

​ ● 自动资源管理:避免手动内存管理,减少内存泄漏风险。

​ ● 小对象优化:对于小 JSON 对象(如只含几个字段),直接在栈上分配内存,减少堆分配开销。

​ ● 编译时检查:编译的时候检查类型,类型安全。

​ ● 基准测试:在处理中等大小 JSON(1MB)时,nlohmann/json 的解析速度通常比其他 C++ 库快 20%~50%。

​ ● 支持STL 风格接口:支持容器式操作和迭代器支持。

c++ 复制代码
for (auto& element : j["hobbies"]) {  // 支持范围for循环
    std::cout << element << std::endl;
}

j["scores"].push_back(95);  // 类似vector的操作
c++ 复制代码
for (auto it = j.begin(); it != j.end(); ++it) {
    std::cout << it.key() << ": " << it.value() << std::endl;
}

​ ● 自动序列化 / 反序列化:支持序列化和反序列化。

c++ 复制代码
struct Person {
    std::string name;
    int age;
};

// 只需定义to_json/from_json函数
void to_json(json& j, const Person& p) {
    j = {{"name", p.name}, {"age", p.age}};
}

void from_json(const json& j, Person& p) {
    p.name = j.at("name").get<std::string>();
    p.age = j.at("age").get<int>();
}

// 使用示例
Person p = {"Alice", 30};
json j = p;  // 自动序列化
Person p2 = j.get<Person>();  // 自动反序列化
相关推荐
知识分享小能手1 小时前
Vue3 学习教程,从入门到精通,使用 VSCode 开发 Vue3 的详细指南(3)
前端·javascript·vue.js·学习·前端框架·vue·vue3
pay4fun1 小时前
2048-控制台版本
c++·学习
知识分享小能手2 小时前
Bootstrap 5学习教程,从入门到精通,Bootstrap 5 表单验证语法知识点及案例代码(34)
前端·javascript·学习·typescript·bootstrap·html·css3
hjjdebug2 小时前
ffplay6 播放器关键技术点分析 1/2
c++·ffmpeg·音视频
racerun3 小时前
UniApp中的pages.json 和 tabBar
uni-app·json
巴伦是只猫3 小时前
【机器学习笔记 Ⅲ】4 特征选择
人工智能·笔记·机器学习
不爱说话的采儿3 小时前
UE5详细保姆教程(第四章)
笔记·ue5·游戏引擎·课程设计
weixin_418813873 小时前
Python-可视化学习笔记
笔记·python·学习
Haoea!3 小时前
Flink-05学习 接上节,将FlinkJedisPoolConfig 从Kafka写入Redis
学习·flink·kafka
Azxcc04 小时前
C++异步编程入门
开发语言·c++