当前位置: 首页 > news >正文

【C++】JSON核心数据结构解析及JSONCPP使用

文章目录

  • json中的常见数据结构
      • 一、基础数据类型(原子结构)
      • 二、核心复合结构
        • 1. JSON对象(Object)
        • 2. JSON数组(Array)
      • 三、常见组合结构(实际开发高频)
        • 1. “对象+数组”:列表型数据
        • 2. “数组+对象”:纯列表数据
        • 3. 嵌套对象:多层级数据
        • 4. 数组嵌套数组:多维数据
      • 四、关键注意事项
      • 总结
  • jsoncpp数据结构
      • 一、核心基础类:Json::Value
        • 1. Json::Value的类型枚举(对应JSON基础类型)
        • 2. Json::Value的核心操作方法
      • 二、JsonCpp核心数据结构(对应JSON复合结构)
        • 1. JSON对象 → Json::Value(objectValue类型)
        • 2. JSON数组 → Json::Value(arrayValue类型)
        • 3. 嵌套结构(对象嵌套对象/数组)
      • 三、辅助核心类(解析/序列化)
        • 示例:解析JSON字符串为Json::Value
      • 四、关键注意事项
      • 总结

json中的常见数据结构

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,基于JavaScript对象语法,但独立于编程语言,其核心是通过键值对组织数据,支持多种基础数据结构和复合结构。以下是JSON中最常见的数据结构,结合示例和特点详细说明:

一、基础数据类型(原子结构)

JSON的基础类型是构成复杂结构的最小单元,共6种核心类型:

类型说明示例
字符串双引号包裹的Unicode字符,支持转义(\"/\\/\//\b/\f/\n/\r/\t/\uXXXX"name": "张三"
数字整数、浮点数,支持负数、科学计数法(无八进制/十六进制)"age": 25,"price": 99.9,"count": 1e3
布尔值true/false(小写,无引号)"isStudent": true
null表示空值(小写,无引号)"address": null
对象键值对的无序集合(复合类型,下文详细说明){"id": 1, "name": "李四"}
数组有序的值列表(复合类型,下文详细说明)["苹果", "香蕉", 3.14]

注意:JSON中不支持undefined、函数、日期(需转为字符串/数字)、正则表达式等JavaScript特有的类型。

二、核心复合结构

1. JSON对象(Object)
  • 定义:以{}包裹的无序键值对集合,键必须是双引号包裹的字符串,值可以是任意JSON基础类型/复合类型。
  • 语法规则
    • 键值对之间用,分隔,最后一个键值对后不能加逗号(否则解析报错);
    • 键和值之间用:分隔;
    • 键必须是字符串(单引号/无引号均不合法)。
  • 示例
{"id":1001,"userInfo":{"username":"zhangsan","email":"zhangsan@example.com"},"hobbies":["篮球","阅读"],"isVip":false,"score":null}
  • 特点
    • 无序性:键值对的顺序不影响解析(不同解析器可能保留顺序,但标准不保证);
    • 嵌套性:值可以是另一个JSON对象(实现多层数据结构)。
2. JSON数组(Array)
  • 定义:以[]包裹的有序值列表,值可以是任意JSON基础类型/复合类型(数组元素类型可不同)。
  • 语法规则
    • 元素之间用,分隔,最后一个元素后不能加逗号
    • 数组长度可通过索引获取(从0开始)。
  • 示例
[101,"李四",{"age":28,"city":"北京"},[1.80,75.5],true,null]
  • 典型场景:表示列表数据(如用户列表、商品列表):
{"students":[{"id":1,"name":"小明","grade":90},{"id":2,"name":"小红","grade":95}]}
  • 特点
    • 有序性:元素顺序固定,可通过索引访问;
    • 异构性:数组内可混合不同类型的值(如数字、字符串、对象)。

三、常见组合结构(实际开发高频)

1. “对象+数组”:列表型数据

最常用的结构,外层是对象(包含元信息),内层数组存放具体列表项:

{"code":200,// 状态码"msg":"请求成功",// 提示信息"data":{// 数据体"total":100,// 总条数"list":[// 列表数据{"id":1,"name":"商品1","price":99},{"id":2,"name":"商品2","price":199}]}}
2. “数组+对象”:纯列表数据

直接返回数组,每个元素是对象(适用于简单列表):

[{"date":"2026-01-01","temperature":10},{"date":"2026-01-02","temperature":12}]
3. 嵌套对象:多层级数据

对象的值是另一个对象,实现数据的层级划分:

{"user":{"basic":{"name":"王五","age":30},"contact":{"phone":"13800138000","address":{"province":"广东","city":"深圳"}}}}
4. 数组嵌套数组:多维数据

适用于矩阵、坐标等场景:

{"matrix":[[1,2,3],[4,5,6],[7,8,9]],"points":[[10,20],[30,40],[50,60]]}

四、关键注意事项

  1. 语法严格性
    • 键必须用双引号({"name": "张三"}合法,{name: "张三"}/{'name': '张三'}不合法);
    • 末尾不能有多余逗号(如[1,2,]/{"a":1,}解析报错);
    • 数字不能以0开头(除0本身,如0123不合法);
  2. 空结构:空对象{}、空数组[]是合法的,常用于默认值;
  3. 解析兼容性:所有主流编程语言(Java/Python/Go/JavaScript等)都有JSON解析库,可将JSON字符串转为对应语言的对象/数组(如JavaScript的JSON.parse(),Python的json.loads())。

总结

JSON的核心是对象(无序键值对)数组(有序值列表)两大复合结构,结合字符串、数字、布尔值、null四种基础类型,可灵活组合出各种复杂数据形态,是前后端交互、配置文件、数据存储的首选格式。实际开发中,最常用的是“对象包裹数组”的列表结构,需严格遵守JSON语法规则以避免解析错误。

jsoncpp数据结构

JsonCpp是C++中最常用的JSON解析/序列化库,其核心围绕Json::Value(表示任意JSON值)和辅助类(如Json::Reader/Json::Writer)构建,所有JSON数据结构最终都映射为Json::Value的不同类型。以下是JsonCpp中核心数据结构、用法及对应JSON结构的映射关系,结合示例详细说明:

一、核心基础类:Json::Value

Json::Value是JsonCpp的核心,可表示JSON支持的所有数据类型(字符串、数字、布尔、null、对象、数组),是一个“万能容器”,通过类型区分和方法调用操作不同JSON结构。

1. Json::Value的类型枚举(对应JSON基础类型)

JsonCpp通过Json::ValueType枚举定义了Json::Value的类型,与JSON原生类型一一对应:

Json::ValueType枚举值对应JSON类型说明示例初始化
nullValuenull空值Json::Value val;(默认null)
intValue整数32位整数(超出用uintValue/realValueJson::Value val(100);
uintValue无符号整数无符号32位整数Json::Value val((unsigned int)200);
realValue浮点数双精度浮点数Json::Value val(3.1415);
stringValue字符串UTF-8字符串Json::Value val("hello json");
booleanValue布尔值true/falseJson::Value val(true);
arrayValue数组有序值列表Json::Value val(Json::arrayValue);
objectValue对象无序键值对(键为字符串)Json::Value val(Json::objectValue);
2. Json::Value的核心操作方法
操作类型方法示例说明
类型判断val.isNull()/val.isInt()/val.isArray()判断当前Value的类型
取值(基础类型)val.asInt()/val.asString()/val.asBool()转为对应C++类型(类型不匹配返回默认值)
数组操作val.append(123)/val[0]/val.size()追加元素、索引访问、获取数组长度
对象操作val["name"] = "张三"/val.get("age", 0)键值赋值、按键取值(无则返回默认值)
遍历(对象)Json::Value::Members keys = val.getMemberNames()获取所有键名,遍历键值对
遍历(数组)for (int i=0; i<val.size(); i++) { val[i]; }按索引遍历数组元素

二、JsonCpp核心数据结构(对应JSON复合结构)

1. JSON对象 → Json::Value(objectValue类型)
  • 映射关系:JSON对象{"key": value}对应Json::ValueobjectValue类型,通过字符串键访问值。
  • 示例代码
#include<json/json.h>#include<iostream>intmain(){// 1. 构建JSON对象Json::Valueuser(Json::objectValue);user["id"]=1001;// intValueuser["name"]="张三";// stringValueuser["isVip"]=true;// booleanValueuser["score"]=Json::nullValue;// nullValueuser["price"]=99.9;// realValue// 2. 访问对象值std::cout<<"ID: "<<user["id"].asInt()<<std::endl;std::cout<<"Name: "<<user["name"].asString()<<std::endl;// 安全取值(键不存在时返回默认值0)std::cout<<"Age: "<<user.get("age",0).asInt()<<std::endl;// 3. 遍历对象所有键值对Json::Value::Members keys=user.getMemberNames();for(constauto&key:keys){std::cout<<key<<": "<<user[key]<<std::endl;}return0;}
  • 输出
ID: 1001 Name: 张三 Age: 0 id: 1001 name: "张三" isVip: true score: null price: 99.9
2. JSON数组 → Json::Value(arrayValue类型)
  • 映射关系:JSON数组[v1, v2, v3]对应Json::ValuearrayValue类型,通过索引访问元素(索引从0开始)。
  • 示例代码
#include<json/json.h>#include<iostream>intmain(){// 1. 构建JSON数组Json::Valuehobbies(Json::arrayValue);hobbies.append("篮球");// 追加字符串hobbies.append("阅读");// 追加字符串hobbies.append(25);// 追加整数hobbies.append(3.14);// 追加浮点数// 2. 访问数组元素std::cout<<"数组长度: "<<hobbies.size()<<std::endl;std::cout<<"第一个元素: "<<hobbies[0].asString()<<std::endl;std::cout<<"第四个元素: "<<hobbies[3].asDouble()<<std::endl;// 3. 遍历数组for(inti=0;i<hobbies.size();++i){std::cout<<"索引"<<i<<": "<<hobbies[i]<<std::endl;}return0;}
  • 输出
数组长度: 4 第一个元素: 篮球 第四个元素: 3.14 索引0: "篮球" 索引1: "阅读" 索引2: 25 索引3: 3.14
3. 嵌套结构(对象嵌套对象/数组)

实际开发中最常用的组合,对应JSON的嵌套结构,核心是Json::Value的嵌套赋值。

  • 示例:对象嵌套对象+数组
#include<json/json.h>#include<iostream>#include<string>intmain(){// 外层对象Json::Valueroot(Json::objectValue);root["code"]=200;root["msg"]="请求成功";// 内层数据对象Json::Valuedata(Json::objectValue);data["total"]=2;// 内层数组(列表数据)Json::Valuelist(Json::arrayValue);// 数组元素1Json::Valueitem1(Json::objectValue);item1["id"]=1;item1["name"]="商品1";item1["price"]=99.9;list.append(item1);// 数组元素2Json::Valueitem2(Json::objectValue);item2["id"]=2;item2["name"]="商品2";item2["price"]=199.9;list.append(item2);// 组装嵌套结构data["list"]=list;root["data"]=data;// 序列化输出(美化格式)Json::StyledWriter writer;std::string jsonStr=writer.write(root);std::cout<<jsonStr<<std::endl;return0;}
  • 输出(格式化后的JSON)
{"code":200,"msg":"请求成功","data":{"total":2,"list":[{"id":1,"name":"商品1","price":99.9},{"id":2,"name":"商品2","price":199.9}]}}

三、辅助核心类(解析/序列化)

JsonCpp的“数据结构”不仅包含Json::Value,还包括用于解析JSON字符串、序列化Json::Value的辅助类:

类名作用核心方法
Json::Reader解析JSON字符串为Json::Valuebool parse(const std::string& jsonStr, Json::Value& root)
Json::Writer抽象类,序列化Json::Value为字符串子类实现std::string write(const Json::Value& root)
Json::FastWriter轻量级序列化(无格式化,单行字符串)继承Writer,输出紧凑JSON
Json::StyledWriter美化序列化(带缩进、换行)继承Writer,输出易读的格式化JSON
Json::StyledStreamWriter流式美化序列化(直接写入流)void write(std::ostream& os, const Json::Value& root)
示例:解析JSON字符串为Json::Value
#include<json/json.h>#include<iostream>#include<string>intmain(){// JSON字符串std::string jsonStr=R"({ "name": "李四", "age": 28, "hobbies": ["游泳", "跑步"], "isMarried": false })";// 解析器Json::Reader reader;Json::Value root;// 解析JSON字符串if(!reader.parse(jsonStr,root)){std::cerr<<"解析失败: "<<reader.getFormattedErrorMessages()<<std::endl;return1;}// 访问解析后的数据std::cout<<"姓名: "<<root["name"].asString()<<std::endl;std::cout<<"年龄: "<<root["age"].asInt()<<std::endl;std::cout<<"第一个爱好: "<<root["hobbies"][0].asString()<<std::endl;return0;}

四、关键注意事项

  1. 类型安全
    • 调用asInt()/asString()等方法时,需确保Json::Value的类型匹配(如nullValue调用asInt()会返回0,无报错但可能逻辑异常);
    • 建议先通过isInt()/isString()等判断类型,再取值。
  2. 空值处理
    • 默认构造的Json::ValuenullValue,可通过isNull()判断;
    • 访问不存在的键/索引时,会返回一个nullValueJson::Value(而非崩溃)。
  3. 编码问题
    • JsonCpp默认处理UTF-8编码,若JSON字符串是GBK/GB2312,需先转换为UTF-8再解析。
  4. 版本差异
    • JsonCpp 1.9.x+ 推荐使用Json::CharReader/Json::CharReaderBuilder替代Json::ReaderReader已标记为过时),示例:
      Json::CharReaderBuilder builder;std::unique_ptr<Json::CharReader>reader(builder.newCharReader());std::string err;boolok=reader->parse(jsonStr.c_str(),jsonStr.c_str()+jsonStr.size(),&root,&err);

总结

JsonCpp的核心数据结构是Json::Value,它通过不同类型(objectValue/arrayValue/intValue等)映射JSON的所有原生结构,配合Reader(解析)和Writer(序列化)类,实现JSON与C++数据的双向转换。实际开发中,最常用的是objectValue(JSON对象)和arrayValue(JSON数组)的嵌套组合,需重点掌握Json::Value的赋值、访问、遍历方法,以及解析/序列化的基本流程。

http://www.jsqmd.com/news/196357/

相关文章:

  • 2025终极指南:如何构建高性能家庭自动化中心——智能家居爱好者的完整搭建教程
  • 谷歌浏览器密码管理器与Fun-ASR无关但都很实用
  • 从零实现Allegro SPB环境下的Gerber导出
  • 新手入门必看:同或门组合电路基础
  • 谷歌浏览器书签管理器集成Fun-ASR语音搜索
  • HandheldCompanion:Windows掌机控制难题的终极解决方案指南
  • Vivado 2019.2安装步骤图解说明(附破解方法)
  • 革命性3D打印螺纹优化方案:CustomThreads让Fusion 360完美适配增材制造
  • CSDN博客大赛增设Fun-ASR应用创新奖项
  • Origin多图层叠加说明语音分别标注实践
  • 黑苹果终极指南:从零到一的完整安装教程
  • ImageStrike:18种图像隐写分析技术完整指南
  • 喜马拉雅音频本地化下载工具使用指南
  • es核心要点:集群、节点与分片概念
  • Origin图表标题和坐标轴标签语音快速设置
  • Origin三维曲面图语音标注坐标含义
  • 谷歌学术之外:Fun-ASR助力中文科研语音处理
  • ModbusPoll轮询周期优化策略:性能提升指南
  • Keras 3.0 教程:端到端深度学习项目指南
  • CSDN私享课预告:深入剖析Fun-ASR源码
  • 通俗解释es中RESTful接口工作方式
  • Audio Slicer 终极指南:告别繁琐手动剪辑,智能音频分割一键搞定
  • LUT调色行业白皮书引用Fun-ASR使用数据
  • 华三交换机忘记密码怎么办
  • CSDN博客推荐:2025年最值得尝试的开源ASR工具
  • 微pe启动原理借鉴:制作GLM-TTS专用系统U盘
  • 华为交换机、路由器和防火墙忘记密码了怎么办
  • LaTeX章节标题层级结构语音构建
  • Origin实验数据标签语音录入效率提升实验
  • 锐捷交换机忘记密码怎么办