【学习笔记】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>();  // 自动反序列化
相关推荐
胡楚昊2 小时前
B站pwn教程笔记-11
笔记
njsgcs4 小时前
gcn graphsage 视频笔记
笔记
虾球xz4 小时前
CppCon 2016 学习:GAME ENGINE USING C++11
大数据·开发语言·c++·学习
Jet45054 小时前
第100+42步 ChatGPT学习:R语言实现阈值调整
开发语言·学习·chatgpt·r语言
虾球xz4 小时前
CppCon 2016 学习:fixed_point Library
开发语言·c++·学习
C语言小火车5 小时前
【C语言】银行账户管理系统丨源码+解析
c语言·c++·算法·课程设计
忘川w6 小时前
网络安全相关知识
笔记·网络安全
寄思~6 小时前
Python学习笔记:错误和异常处理
开发语言·笔记·python·学习
啊哈哈哈哈哈啊哈哈6 小时前
G2打卡——人脸图像生成
pytorch·学习·gan