轻量级数据交换格式:jsoncpp

news2024/12/26 23:22:44

 "这不属于我,因为沉默背后,也有冲动"


一、认识json

(1) 为什么有那么多的数据交换格式?

        比如说,现在我有下面的数据:

#include <iostream>
#include <string>

int main()
{
    std::string name = "张三";
    int age = 18;
    std::string add = "China";
    std::string email = "12321312@163.com";
    return 0;
}

        我想通过网路进行传输,这些从语言上来看定义出的数据,我该用什么样的方式。可是,一旦程序进行编译后,任何数据都是二进制代码,完全不便于人们进行观察。

        因此,为了便于人阅读、编写,机器的生成和解析,json、protobuf等常见的数据交换格式接踵而至,在提高可读性的同时,有效提升了网络传输的效率。

(2) json简介

JSON 是一种轻量级的数据交换格式。采用完全独立于计算机语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。

                                                                                                                        取自这里


二、Jsoncpp

(1) Jsoncpp安装

# 查看自己库中是否安装了jsoncpp
rpm -qa | grep jsoncpp

         如果没有,可以看看在yum源里查查看:

# 安装命令
sudo yum install -y jsoncpp-devel-0.10.5-2.el7.x86_64

        安装完成后,我们可以在 /usr/include/jsoncpp路径下找到这些头文件:

         usr/lib64 下的动静态库:

(2) Jsoncpp数据格式

        这里我们想要表示一个学生的信息,用C语言表示:

char* name = "张三";
int age = 18;
float score[3] = {88.5,92.3,90.5};

        如果我们用Json表示这一条语句呢:

{
    "姓名":"张三";
    "年龄":18,
    "成绩": [85.5,92.3,90.3]
}

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

•对象: 使用花括号 {} 

•数组: 使用中括号 [] 

•字符串: 使用常规的双引号("")

•数字:包括整形和浮点型,直接使⽤

(3) Jsoncpp接口介绍 

        Jsoncpp库主要用于json格式数据的 序列化 与 反序列化。

        我们先来看看json对象的对象类表示:

class Json::Value{
    //Value重载了[]和=,因此所有的赋值和获取
    Value &operator=(const Value &other); 
    // "[]" 可以采用更简答的方式存储数据 val["name"] = xxx
    Value& operator[](const char* key);
    Value& operator[](const std::string& key);
       
    Value removeMember(const char* key);//移除元素
    
    // 数组访问 val["score"][0]
    const Value& operator[](ArrayIndex index) const;
    // 用于数组添加!
    Value& append(const Value& value);//添加数组元素val["score"].append(88);
    //获取数组元素个数
    ArrayIndex size() const;
    
    // 我们正常获得的是数据对象 而不是数据本身
    // 但我们可以根据Value 获取数据本身
    std::string asString() const;
    const char* asCString() const;
    Int asInt() const;
    float asFloat() const;
    bool asBool() const;
}

        Jsoncpp 库主要借助三个类以及其对应的少量成员函数完成序列化及反序列化
• 序列化接⼝

// 这个是工厂函数 需要定义出来 new StreamWriter()
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
    virtual StreamWriter* newStreamWriter() const;
}

class JSON_API StreamWriter {
    virtual int write(Value const& root, std::ostream* sout) = 0;
}

• 反序列化接⼝:

// 同上
class JSON_API CharReaderBuilder : public CharReader::Factory {
    virtual CharReader* newCharReader() const;
}

class JSON_API CharReader {
    virtual bool parse(char const* beginDoc, char const* endDoc,
    Value* root, std::string* errs) = 0;
}


        我们完成了简单的json序列化反序列化接口的认识,我们"乘火打劫",写个简单的序列化反序列化代码。

三、 简易的序列化反序列化

序列化:

① 创建Json::Value 对象

② 创建工厂对象StreamWriterBuilder

③ 调用工厂函数对象方法 new StreamWriter() 获取序列化接口

④ 调用 write()接口

⑤ 获取序列化后的字符串返回

反序列化:

① 创建Json::Value 对象

② 创建工厂对象 CharReaderBuilder

③ 调用工厂函数对象方法 new CharReader() 获取序列化接口

④ 调用 parse()接口

⑤ 反序列化后的内容 在Json::Value的对象里

 序列化:

        对于write而言,都会返回0。如果感觉到数据序列化出错,相反应该检查stream流。

std::string serialization()
{
    Json::Value root;
    root["姓名"] = "张三";
    root["年龄"] = 18;
    root["成绩"].append(93.2);
    root["成绩"].append(83.2);
    root["成绩"].append(90.2);

    Json::StreamWriterBuilder swb;
    Json::StreamWriter* sw = swb.newStreamWriter();
    
    // 是将root的对象数据序列化到一个字符串里
    std::stringstream ss;
    sw->write(root,&ss);

    return ss.str();
}

 

反序列化:

bool deserialization(const std::string &str)
{
    Json::Value root;

    Json::CharReaderBuilder crb;
    Json::CharReader* cr = crb.newCharReader();

    std::string err;
    bool ret = cr->parse(str.c_str(),str.c_str()+str.size(),&root,&err);
    if(ret == false){
        std::cout << "Json Parse Faild: " << err << std::endl;
        return false;
    }

    // 访问root内容
    std::cout << "姓名: " << root["姓名"].asCString() << std::endl;
    std::cout << "年龄: " << root["年龄"].asInt() << std::endl;
    int size = root["成绩"].size();
    for(int i=0; i<size; ++i){
        std::cout << "成绩" << i+1 << ": " << root["成绩"][i].asFloat() << std::endl;
    }

    return true;
}

 


本篇花了一些小篇幅讲了讲常用的数据交换格式:Json。

感谢你的阅读,

祝你好运,向阳而生~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

比较两个突出的node.js框架:koa和express

目录 一、Koa 和 Express 的介绍 二、Koa 和 Express 的区别 1.异步编程方式不同 2.错误处理方式不同 三、Koa 和 Express 的优缺点 1.Express 的优点 2.Express 的缺点 3.Koa 的优点 4.Koa 的缺点 总结 接上文讲述了 koa框架&#xff0c;这边文章比较一下这两个突出…

CentOS系统忘记密码了改怎么修改重置103.88.34.X

首先&#xff0c;打开centos7&#xff0c; 在正常系统入口按↑和↓"e"&#xff0c;会进入edit模式 然后找到以“Linux16”开头的行&#xff0c;在该行的最后面输入“init/bin/sh” 按下ctrlx组合键来启动系统 接下来再输入“mount -o remount,rw /”(注意mount与…

ceph对象存储使用总结

ceph对象存储使用总结 大纲 基础概念安装对象存储网关RADOS网关配置对象存储网关RADOS网关修改RADOS网关端口修改支持https访问RADOS网关使用s3cmd操作对象存储Ceph dashboard管理RADOS网关使用java程序操作对象存储 基础准备 操作系统 ubuntu~18.04ceph版本 Octopus v15.2…

适用于 3DS Max 和 Cinema 4D 的 Chaos Corona 10重磅推出!

Chaos 发布了 Corona 10&#xff0c;适用于3DS Max和Cinema 4D 的渲染器的最新版本 &#xff01;Corona 10 对软件的多项现有功能进行了更新&#xff0c;包括贴花、体积渲染、景深和程序云。 目前渲云云渲染已支持Corona 10&#xff0c;支持批量渲染&#xff0c;批量出结果&am…

chatgpt赋能python:介绍Python语言

介绍Python语言 Python是一门易学易用的编程语言&#xff0c;它被广泛应用于各种领域&#xff0c;包括数据科学、机器学习、人工智能、Web开发等。自1991年首次推出以来&#xff0c;Python不断演进和发展&#xff0c;如今已经成为行业内一种不可或缺的编程语言。它在可读性和语…

chatgpt赋能python:Python词汇量为什么很重要?

Python词汇量为什么很重要&#xff1f; 作为一个有10年Python编程经验的工程师&#xff0c;我有着非常深刻的体会&#xff0c;词汇量对于掌握这门编程语言来说是非常重要的。在这篇文章中&#xff0c;我将重点讨论Python词汇量为什么很重要&#xff0c;以及如何提升你的Python…

STM32的五个时钟源

①HSI是高速内部时钟&#xff0c;RC振荡器&#xff0c;频率为8MHz。 ②HSE是高速外部时钟&#xff0c;可接石英/陶瓷谐振器&#xff0c;或者接外部时钟源&#xff0c;频率范围为4MHz~16MHz。 ③LSI是低速内部时钟&#xff0c;RC振荡器&#xff0c;频率为40kHz。 ④LSE是低速外…

2核4G服务器_4M带宽_CPU性能测评_60G系统盘

阿里云2核4G服务器297元一年、4M公网带宽、60G系统盘&#xff0c;阿里云轻量应用服务器2核4G4M带宽配置一年297.98元&#xff0c;2核2G3M带宽轻量服务器一年108元12个月&#xff0c;如下图&#xff1a; 目录 阿里云2核4G4M轻量应用服务器 2核4G服务器限制条件 轻量服务器介…

使用Spring Boot、MyBatis Plus和Elasticsearch的简单示例

下面是一个使用Spring Boot、MyBatis Plus和Elasticsearch的简单示例&#xff1a; 首先&#xff0c;在pom.xml文件中添加以下依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elast…

《Pytorch深度学习和图神经网络(卷 1)》学习笔记——第五章

全连接神经网络 隐藏层的节点数决定了模型拟合能力&#xff0c;如果在单隐藏层设置足够多的节点&#xff0c;理论上可以拟合世界上各种维度的数据进行任意规则的分类&#xff0c;但会过拟合。 隐藏层的数量决定了其泛化能力&#xff0c;层数越多&#xff0c;推理的能力越强&am…

【前端工具】使用Echats生成关系图谱,可展开折叠

目录 一、需求背景与效果 二、echarts源码 一、需求背景与效果 根据服务关系制作关系图谱&#xff0c;echarts官方关系图没有想要的案例&#xff0c;网上也没有好的效果&#xff0c;故参考网上已有的部分案例&#xff0c;自行写了一个&#xff0c;效果还不错。 当前echarts…

Centos7单机安装Redis

安装Redis依赖 Redis是基于C语言&#xff0c;因此首先需要安装Redis所需要的gcc依赖&#xff1a; yum install -y gcc tcl ​ 上传安装包并解压 上传安装包redis-6.2.12至/home目录下 ​ # 解压 tar -xzf redis-6.2.12.tar.gz # 安装 cd redis-6.2.12 make && mak…

react ant table设置动态scroll,且某些列的长度固定

设置scroll x的值为列的个数*100 1.代码 const columns [ {title: 料号描述,dataIndex: itemDesc,align:left,width: 200,ellipsis: true,} ]<EditableProTableclassName"details-table"columns{columns}loading{loading}rowKey"id"value{dataSource}…

C++笔记之自引用结构体

C笔记之自引用结构体 code review! 文章目录 C笔记之自引用结构体1.在结构体中引用相同类型的结构体&#xff0c;并且可以使用指针或引用来实现。2.自引用结构体构建链表3.自引用结构体构建二叉树附:代码随想录——链表定义附:代码随想录——二叉树定义 1.在结构体中引用相同…

分布式幂等问题解决方案

目录 一 背景 二 什么是幂等 三 解决方案三部曲 第一部曲&#xff1a;识别相同请求 第二部曲&#xff1a;列出并减少副作用的分析维度 第三部曲&#xff1a;识别细粒度副作用&#xff0c;针对性设计解决方案 四 总结 一 背景 分布式系统由众多微服务组成&#xff0c;微…

从0到1搭建Springboot整合Quartz定时任务框架(保姆级教学+Gitee源码)

前言&#xff1a;最近学习了目前主流的若依框架&#xff0c;这是一个非常优秀的开源项目&#xff0c;故此我这边把它的源码全部剖析了一遍&#xff0c;简化了它的框架&#xff0c;我会通过这篇博客详细讲解我是如何进行推敲和从0到1搭建这个项目的流程。 目录 一、Quartz简介 …

Java并发(十二)----线程应用之多线程解决烧水泡茶问题

1、背景 统筹方法&#xff0c;是一种安排工作进程的数学方法。它的实用范围极广泛&#xff0c;在企业管理和基本建设中&#xff0c;以及关系复杂的科研项目的组织与管理中&#xff0c;都可以应用。 怎样应用呢&#xff1f;主要是把工序安排好。 比如&#xff0c;想泡壶茶喝。…

【前后端分离开发及项目部署流程】

文章目录 前后端分离开发技术1 前后端分离开发1.1 介绍1.2 开发流程1.3 前端技术栈&#xff08;了解&#xff09; 2 Yapi&#xff08;定义API接口&#xff09;2.1 介绍2.2 使用 3 Swagger3.1 介绍3.2 使用方式3.3 常用注解 4 项目部署4.1 部署架构4.2 部署环境说明4.3 部署前端…

chatgpt赋能python:如何使用Python访问共享目录——让共享变得简单易行

如何使用Python访问共享目录 —— 让共享变得简单易行 作为一种高效而强大的编程语言&#xff0c;Python拥有各种各样的应用。其中一个非常重要的应用场景就是对共享目录的访问和操作。无论是在家庭网络&#xff0c;企业内网或者云存储平台&#xff0c;共享目录的重要性毋庸置…

两个链表的入环节点(java)

两个链表的入环节点 两个链表的入环节点解题思路代码演示 链表相关的题 两个链表的入环节点 给定两个可能有环也可能无环的单链表&#xff0c;头节点head1和head2 请实现一个函数&#xff0c;如果两个链表相交&#xff0c;请返回相交的第一个节点。如果不相交返回null 要求如果…