JsonCpp超详细使用教程

发布时间:2026/7/22 2:50:16
JsonCpp超详细使用教程 一、JSON是什么JSON全称 JavaScript Object Notation是一种轻量级的数据交换格式。别看它名字里带JavaScript它是完全独立于语言的啥编程语言都能用。JSON的基本结构对象大括号{}包起来里面是键值对数组方括号[]包起来是值的有序集合值可以是字符串、数字、布尔值(true/false)、null、对象、数组语法规则键值对格式key: value键必须用双引号多个键值对之间用逗号,分隔来看个例子就懂了{name:John Doe,age:30,is_student:false,skills:[JavaScript,Python,C],address:{street:123 Main St,city:Anytown,state:CA}}JSON的用途非常广数据交换、配置文件、接口返回值、数据存储几乎无处不在。二、JsonCpp是什么 安装JsonCpp简介JsonCpp是C里最常用的JSON处理库专门用来解析和生成JSON数据的。它的特点简单好用API非常直观上手快高性能解析速度快大数据量也扛得住跨平台Windows、Linux、macOS都支持无依赖不依赖其他外部库集成方便完全支持C11智能指针啥的都用上了安装Ubuntu一条命令搞定sudoaptinstalllibjsoncpp-dev使用的时候记得包含头文件和链接库// 头文件#includejsoncpp/json/json.h# 编译时链接库g main.cc-omain-ljsoncpp三、JsonCpp核心类拆解JsonCpp的核心就三个东西我们逐个拆分理解一下1. Json::Value —— JSON数据的万能容器这是JsonCpp最核心的类不管是对象、数组、字符串、数字统统都用Json::Value来表示。JSON支持的数据类型enumValueType{nullValue0,// null空值intValue,// 有符号整数uintValue,// 无符号整数realValue,// 浮点数doublestringValue,// 字符串booleanValue,// 布尔值arrayValue,// 数组objectValue// 对象};取值方法把Value转成C类型asString()// 转字符串asInt()// 转intasInt64()// 转int64asDouble()// 转doubleasBool()// 转boolasFloat()// 转float判断类型方法isNull()// 是否为空isBool()// 是否是布尔值isInt()// 是否是整数isString()// 是否是字符串isArray()// 是否是数组isObject()// 是否是对象对象操作键值对value[key]xxx;// 用[]直接赋值或取值value[key];// 获取某个键的值isMember(key)// 判断是否存在某个键removeMember(key)// 删除某个键数组操作size()// 获取数组元素个数empty()// 数组是否为空clear()// 清空数组append(value)// 往数组末尾追加元素value[i]// 用下标访问第i个元素2. StreamWriter —— 序列化C数据 → JSON字符串序列化就是把Json::Value对象转成JSON格式的字符串用来输出或者发送。核心套路创建StreamWriterBuilder工厂对象用工厂newStreamWriter()创建写入器调用write()方法把Value写进字符串流3. CharReader —— 反序列化JSON字符串 → C数据反序列化就是把JSON字符串解析成Json::Value对象用来读取数据。核心套路创建CharReaderBuilder工厂对象用工厂newCharReader()创建读取器调用parse()方法解析字符串到Value四、序列化实战——生成JSON字符串序列化就是把我们C里的数据组织成JSON格式的字符串。话不多说直接上代码#includeiostream#includesstream#includejsoncpp/json/json.hintmain(intargc,char*argv[]){// 第一步组织JSON数据 // 先创建一个子对象addressJson::Value item;item[street]123 Main St;// 字符串item[city]Anytown;item[state]CA;// 创建根对象Json::Value value;value[name]John Doe;// 字符串value[age]30;// 整数value[is_student]false;// 布尔值// 数组用append逐个追加value[skills].append(JavaScript);value[skills].append(Python);value[skills].append(C);// 嵌套对象直接把整个item赋值过去value[address]item;// 第二步序列化输出 // 1. 创建StreamWriter工厂对象Json::StreamWriterBuilder swb;// 可选配置要不要格式化输出缩进换行// swb.settings_[indentation] ; // 设为空就是压缩成一行// 2. 用工厂创建StreamWriter对象智能指针自动释放std::unique_ptrJson::StreamWriterpsw(swb.newStreamWriter());// 3. 用字符串流接收结果std::stringstream ss;try{// 序列化把value写入sspsw-write(value,ss);// 输出JSON字符串std::coutss.str()std::endl;}catch(Json::Exceptione){std::coutError:e.what()std::endl;}return0;}运行结果{address:{city:Anytown,state:CA,street:123 Main St},age:30,is_student:false,name:John Doe,skills:[JavaScript,Python,C]}五、反序列化实战——解析JSON字符串反序列化就是把JSON字符串解析出来读取里面的各个字段。这是实际开发中用得最多的场景#includeiostream#includejsoncpp/json/json.husingnamespacestd;intmain(intargc,char*argv[]){// 第一步准备JSON字符串 // 用C11的原始字符串R(...)写JSON超方便不用转义双引号string strR( { address:{ city:Anytown, state:CA, street:123 Main St }, age:30, is_student:false, name:John Doe, skills:[JavaScript,Python,C] } );// 第二步反序列化解析 // 用来接收解析结果的Value对象Json::Value value;// 1. 创建CharReader工厂对象Json::CharReaderBuilder build;// 2. 用工厂创建CharReader对象unique_ptrJson::CharReaderpcr(build.newCharReader());// 用来接收错误信息string err;// 3. 开始解析// 参数字符串起始地址、结束地址、结果接收、错误信息boolretpcr-parse(str[0],str[str.size()],value,err);if(retfalse){coutError: errendl;return-1;}// 第三步读取解析后的数据 // 读取普通字段先判断字段是否存在再转对应类型if(!value[name].isNull())coutname: value[name].asString()endl;if(!value[age].isNull())coutage: value[age].asInt()endl;if(!value[is_student].isNull())coutis_student: value[is_student].asBool()endl;// 不存在的字段不会报错isNull()返回trueif(!value[weight].isNull())coutweight: value[weight].asFloat()endl;// 读取数组先判断是不是数组再用size()和下标遍历if(!value[skills].isNull()value[skills].isArray()){intszvalue[skills].size();// 获取数组长度for(inti0;isz;i){coutskills: value[skills][i].asString()endl;}}// 读取嵌套对象一层层[]往里取就行if(!value[address].isNull()value[address].isObject()){coutaddress.street: ;coutvalue[address][street].asString()endl;coutaddress.city: ;coutvalue[address][city].asString()endl;coutaddress.state: ;coutvalue[address][state].asString()endl;}return0;}运行结果name: John Doe age: 30 is_student: 0 skills: JavaScript skills: Python skills: C address.street: 123 Main St address.city: Anytown address.state: CA小提示读取字段前最好先用isNull()判断一下存不存在防止访问不存在的字段出问题这是好习惯哦六、Makefile编译参考all: serialize unserialize serialize: serialize.cc g -stdc11 $^ -o $ -ljsoncpp unserialize: unserialize.cc g -stdc11 $^ -o $ -ljsoncppmake一下两个程序就都编译好了非常方便。总结JsonCpp的核心知识点我们梳理一下三大核心类Json::Value—— 万能容器存各种JSON数据用[]访问键值append追加数组StreamWriterBuilder—— 序列化工厂把Value转成JSON字符串CharReaderBuilder—— 反序列化工厂把JSON字符串解析成Value常用操作取值asString() / asInt() / asBool() / asDouble()判断isNull() / isArray() / isObject() / isMember()对象value[key]直接读写数组append() / size() / value[i]最佳实践读取字段前先判断isNull()避免访问不存在的字段C11以上用原始字符串R()写JSON不用转义双引号用智能指针管理StreamWriter和CharReader自动释放内存