【C++】JsonCpp库

目录

前置知识

Json数据格式

JsonCpp介绍

安装jsoncpp库

头文件

使用介绍

使用示例

序列化

反序列化


前置知识

Json数据格式

Json数据格式是一种数据交换格式,采用完全独立于编程语言的文本格式存储和表示数据。

例如:表示一个学生信息

{

        "姓名":"xxx",

        "年龄":18,

        "成绩":[88.5,99,58]

}

Json的数据类型包括对象,字符串,数字等 

  • 对象:使用花括号{ }括起来的表示一个对象
  • 数组:使用中括号[ ]括起来的表示一个数组
  • 字符串:使用常规双引号“”括起来的一个字符串
  • 数字:包括整型和浮点型,直接使用

JsonCpp介绍

安装jsoncpp库

Linux环境下(ubuntu)

sudo apt-get install libjsoncpp-dev

头文件

在使用前,需要先引入jsoncpp的头文件

#include<jsoncpp/json/json.h>

使用介绍

JsonCpp库是用来实现Json数据格式的序列化和反序列化,主要涉及三个类:

1、Json::Value类:中间数据存储类

如果要将数据进行序列化,就需要先存储到Json::Value对象中;

如果要将数据进行反序列化,就是解析后,将数据对象放入到Json::Value对象中

如下是Json数据对象类的表示: 

class Json::Value{
     Value &operator=(const Value &other); //Value重载了[]和=,因此所有的赋值和获取
数据都可以通过
     Value& operator[](const std::string& key);//简单的⽅式完成 val["name"] = 
"xx";
     Value& operator[](const char* key);
     Value removeMember(const char* key);//移除元素
     const Value& operator[](ArrayIndex index) const; //val["score"][0]
     Value& append(const Value& value);//添加数组元素val["score"].append(88); 
     ArrayIndex size() const;//获取数组元素个数 val["score"].size();
     std::string asString() const;//转string string name = val["name"].asString();
     const char* asCString() const;//转char* char *name = val["name"].asCString();
     Int asInt() const;//转int int age = val["age"].asInt();
     float asFloat() const;//转float float weight = val["weight"].asFloat();
     bool asBool() const;//转 bool bool ok = val["ok"].asBool();
};

2、序列化接口

  • Json::StreamWriter类:用于进行数据序列化
  • Json::StreamWriter::write() 序列化函数
  • Json::StreamWriterBuilder类:Json::StreamWriter工厂类,用于生产一个Json::StreamWriter对象
class JSON_API StreamWriter {
     virtual int write(Value const& root, std::ostream* sout) = 0;
}
//工厂类,生成一个StreamWriter对象
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
     virtual StreamWriter* newStreamWriter() const;
}

PS:

virtual int write(要序列化的Json::Value对象, 输出流对象地址) = 0; 

  • 返回0序列化成功

 3、反序列接口

  • Json::CharReader反序列化类
  • Json::CharReader::parse()反序列化函数
  • Json::CharReaderBuilder 工厂类,用于生产一个Json::CharReader对象
class JSON_API CharReader {
     virtual bool parse(char const* beginDoc, char const* endDoc, 
     Value* root, std::string* errs) = 0;
}
//工厂类
class JSON_API CharReaderBuilder : public CharReader::Factory {
     virtual CharReader* newCharReader() const;
}

PS: 

virtual bool parse((序列化后的字符串)字符串的起始地址, 字符串的结束地址,存放解析结果的Json::Value对象的地址,erro信息)

  • 返回true反序列化成功

使用示例

序列化

#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include <jsoncpp/json/json.h>
bool serialize(Json::Value &val,std::string &body)
{
    std::stringstream ss;
    //先实例化一个工厂类对象
    Json::StreamWriterBuilder swb;
    //获取一个StreamWriter对象
    std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
    int ret=sw->write(val,&ss);
    if(ret!=0)
    {
        std::cout<<"serialize failed!"<<std::endl;
        return false;
    }

    body=ss.str();
    return true;
    
}
int main()
{
    Json::Value student;
    Json::Value fav;//描述爱好
    //填入爱好
    fav["书籍"]="骆驼祥子";
    fav["运动"]="打羽毛球";


    student["姓名"]="张三";
    student["年龄"]=19;
    //数组不能直接赋值,需要使用append方法
    student["成绩"].append(100);
    student["成绩"].append(100);
    student["成绩"].append(100);
    //嵌套一个对象
    student["爱好"]=fav;

    std::string body;
    if(serialize(student,body))
    {
        std::cout<<body<<std::endl;
    }

    return 0;
}

编译运行

g++ -std=c++11 jsoncpp_test.cc -o json -ljsoncpp

结果如下:

root@ubuntu:~/demo/jsoncpp# ./json 
{
        "姓名" : "张三",
        "年龄" : 19,
        "成绩" : 
        [
                100,
                100,
                100
        ],
        "爱好" : 
        {
                "书籍" : "骆驼祥子",
                "运动" : "打羽毛球"
        }
}

注意:

  • Json::StreamWriterBuilder工厂类返回的是Json::StreamWriter的指针,因此我们使用完Json::StreamWriter对象后要记得释放,这里采用智能指针对其进行管理。

反序列化

bool unserialize(const std::string &body,Json::Value &val)
{
    //创建Json::CharReaderBuilder 工厂类
    Json::CharReaderBuilder crb;
    //获取一个Json::CharReader对象
    std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
    std::string errs;
    bool ret=cr->parse(body.c_str(),body.c_str()+body.size(),&val,&errs);
    if(ret==false)
    {
        std::cout<<"json unserialize failed:"<<errs<<std::endl;
        return false;
    }
    return true;
}
int main()
{
  
    std::string str=R"({"姓名":"张三","年龄":19,"成绩":[100,100,99]})";
    Json::Value val;
    if(unserialize(str,val))
    {
        std::cout<<"姓名:"<<val["姓名"].asString()<<std::endl;
        std::cout<<"年龄:"<<val["年龄"].asInt()<<std::endl;
        int sz=val["成绩"].size();

        for(int i=0;i<sz;i++)
        {
            std::cout<<"成绩:"<<val["成绩"][i].asFloat()<<std::endl;
        }
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/953012.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【学习笔记】数据结构(十一)

外部排序 文章目录 外部排序11.1 外存信息的存取11.2 外部排序的方法11.3 多路平衡归并的实现 - 增加k11.4 置换-选择排序 - 减少m11.5 最佳归并树 外部排序 指的是大文件的排序&#xff0c;即待排序的记录存储在外存储器 上&#xff0c;在排序过程中需进行多次的内、外存之间的…

《跟我学Spring Boot开发》系列文章索引❤(2025.01.09更新)

章节文章名备注第1节Spring Boot&#xff08;1&#xff09;基于Eclipse搭建Spring Boot开发环境环境搭建第2节Spring Boot&#xff08;2&#xff09;解决Maven下载依赖缓慢的问题给火车头提提速第3节Spring Boot&#xff08;3&#xff09;教你手工搭建Spring Boot项目纯手工玩法…

【Linux笔记】Day1

基于韩顺平老师课程记录&#xff1a; https://www.bilibili.com/video/BV1Sv411r7vd 安装CentOS 给CentOS手动分区 分为三个区&#xff1a; boot分区&#xff08;给1G就行&#xff09; 交换分区&#xff08;和内存相关&#xff0c;这里和虚拟机的内存2G一致&#xff09; …

【网络】:网络编程套接字

目录 源IP地址和目的IP地址 源MAC地址和目的MAC地址 源端口号和目的端口号 端口号 VS 进程ID TCP协议和UDP协议 网络字节序 字符串IP和整数IP相互转换 查看当前网络的状态 socket编程接口 socket常见API 创建套接字 绑定端口号 发送数据 接收数据 sockaddr结构…

使用 Multer 上传图片到阿里云 OSS

文件上传到哪里更好&#xff1f; 上传到服务器本地 上传到服务器本地&#xff0c;这种方法在现今商业项目中&#xff0c;几乎已经见不到了。因为服务器带宽&#xff0c;磁盘 IO 都是非常有限的。将文件上传和读取放在自己服务器上&#xff0c;并不是明智的选择。 上传到云储存…

【端云一体化】云函数的使用

前言 为丰富HarmonyOS对云端开发的支持、实现端云联动&#xff0c;DevEco Studio以Cloud Foundation Kit&#xff08;云开发服务&#xff09;为底座、在传统的“端开发”基础上新增“云开发”能力&#xff0c;开发者在创建工程时选择合适的云开发工程模板&#xff0c;即可在De…

YARN 架构组件及原理

一、YARN 体系架构 YARN&#xff08;Yet Another Resource Negotiator&#xff0c;另一种资源协调者&#xff09; 是 Hadoop 2.0 中的资源管理系统&#xff0c;它的基本设计思想是将 MRv1 中的 JobTracker拆分成了两个独立的服务 &#xff1a;一个全局的资源管理器 ResourceMa…

C# GDI+的DrawString无法绘制Tab键的现象

【啰嗦2句】 现在用C#的人很少了吧&#xff1f;GDI更少了吧&#xff1f;所以这个问题估计也冷门。没关系&#xff0c;分享给特定需要的人也不错。 【问题现象】 工作中开发了一个报告编辑器&#xff0c;实现图文排版等功能&#xff0c;用着没什么问题&#xff0c;直到有一天…

最近在盘gitlab.0.先review了一下docker

# 正文 本猿所在产品的代码是保存到了一个本地gitlab实例上&#xff0c;实例是别的同事搭建的。最近又又又想了解一下&#xff0c;而且已经盘了一些了&#xff0c;所以写写记录一下。因为这个事儿没太多的进度压力&#xff0c;索性写到哪儿算哪儿&#xff0c;只要是新了解到的…

春秋云镜——initial

初步认识内网渗透流程 thinkphp外网打点 打开环境后尝试登陆无果&#xff0c;用fscan扫一下看看 fscan.exe -h 39.99.224.87 发现是think PHP漏洞 补充&#xff1a; fscan&#xff1a;一款内网综合扫描工具&#xff0c;方便一键自动化、全方位漏扫扫描。支持主机存活探测、端…

【C++】string的关系运算与比较分析

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;基础知识&#xff1a;C 中的 string 关系运算器1. 关系运算器概述2. 字符串比较的本质 &#x1f4af;代码解析与扩展代码例一&#xff1a;相等比较代码解析输出 代码例二&a…

Qt C++读写NFC标签NDEF网址URI

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.1d292c1biFgjSs&ftt&id615391857885 #include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> #include "QLibrary" …

NVIDIA Clara平台助力医学影像处理:编程案例与实践探索(上)

一、引言 1.1 研究背景与意义 在现代医学领域,医学影像技术已然成为疾病诊断、治疗方案制定以及疗效评估的关键支柱。从早期的 X 射线成像,到如今的计算机断层扫描(CT)、磁共振成像(MRI)、正电子发射断层扫描(PET)等先进技术,医学影像为医生提供了直观、精准的人体内…

【硬件介绍】Type-C接口详解

一、Type-C接口概述 Type-C接口特点&#xff1a;以其独特的扁头设计和无需区分正反两面的便捷性而广受欢迎。这种设计大大提高了用户的使用体验&#xff0c;避免了传统USB接口需要多次尝试才能正确插入的问题。Type-C接口内部结构&#xff1a;内部上下两排引脚的设计虽然可能不…

【数据结构】第1天之Java中的数据结构

前言 众所周知&#xff0c;程序数据结构算法&#xff0c;可见数据结构的重要性。 在Java中&#xff0c;数据结构通常指的是Java集合框架中的类和接口。 Java集合框架提供了一套标准的数据结构&#xff0c;例如列表、集合、映射表等&#xff0c;以及相应的实现类。 今天要分享的…

Open FPV VTX开源之默认MAVLink设置

Open FPV VTX开源之默认MAVLink设置 1. 源由2. 准备3. 连接4. 安装5. 配置6. 测试6.1 启动wfb-ng服务6.2 启动wfb-ng监测6.3 启动QGroundControl6.4 观察测试结果 7. 总结8. 参考资料9. 补充9.1 telemetry_tx异常9.2 DEBUG串口部分乱码9.3 PixelPilot软件问题9.4 偶尔启动卡住 …

Spring Boot 和微服务:快速入门指南

&#x1f496; 欢迎来到我的博客&#xff01; 非常高兴能在这里与您相遇。在这里&#xff0c;您不仅能获得有趣的技术分享&#xff0c;还能感受到轻松愉快的氛围。无论您是编程新手&#xff0c;还是资深开发者&#xff0c;都能在这里找到属于您的知识宝藏&#xff0c;学习和成长…

Redis 为什么要引入 Pipeline机制?

在 Redis 中有一种 Pipeline&#xff08;管道&#xff09;机制&#xff0c;其目的是提高数据传输效率和吞吐量。那么&#xff0c;Pipeline是如何工作的&#xff1f;它又是如何提高性能的&#xff1f;Pipeline有什么优缺点&#xff1f;我们该如何使用 Pipeline&#xff1f; 1、…

Cesium小知识:粒子系统的参数详解

Cesium 的粒子系统通过 ParticleSystem 类提供了一套丰富的参数来控制粒子的生成、行为和外观。以下是这些参数的详细说明,帮助你更好地理解和使用 Cesium 的粒子系统。 基本参数 image (String) - 粒子图像的URL路径。这个图像是每个粒子在渲染时使用的纹理。 startColor (Co…

【数据结构-堆】力扣1834. 单线程 CPU

给你一个二维数组 tasks &#xff0c;用于表示 n​​​​​​ 项从 0 到 n - 1 编号的任务。其中 tasks[i] [enqueueTimei, processingTimei] 意味着第 i​​​​​​​​​​ 项任务将会于 enqueueTimei 时进入任务队列&#xff0c;需要 processingTimei 的时长完成执行。 现…