Json简述(C++)

目录

1.介绍

2.格式

3.底层

3.1数据对象表示

3.2序列化接口

3.3反序列化接口

4.使用

1.介绍

Json(JavaScript Object Notation)是一种轻量级的数据交换格式,其最早是为JavaScript编程语言设计的格式。不过发发展至今,Json数据格式已经成为了一种独立于语言的文本格式来存储和表示数据。

2.格式

假设,当我们需要表达个人信息时,我们在c语言中常用的做法是设计结构体来进行表述。例如:我们设计student结构体类定义和表述个人信息。

typedef struct {
	int id;
	char* name;
	float score[3];
}student;

int main() {
	student s1 = { 1,"张三",{77.7, 88.8, 99.9} };
	return 0;
}

于是我们便得到了一种封装的学生数据格式,Json提供的也是类似的操作,将数据封装打包。

Json的数据表示形式我们可以通过一段代码来进行查看。

#include<iostream>
#include<string>
#include<memory>
#include<sstream>
#include<jsoncpp/json/json.h>

bool serialize(const Json::Value &root, std::string *out) {
    //Json::StreamWriter
    Json::StreamWriterBuilder swb;
    std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
    std::stringstream ss;
    int ret = sw->write(root, &ss);
    if (ret != 0) {
        std::cerr << "serializer failed\n";
        return false;
    }
    *out = ss.str();
    return true;
}

int main() {
    Json::Value root;
    root["id"] = 1;
    root["name"] = "张三";
    root["score"].append(77.7);
    root["score"].append(88.8);
    root["score"].append(99.9);

    std::string body;
    serialize(root, &body);
    std::cout << body << std::endl;
    return 0;
}

现在我们不用关心上述代码的内容,主要是来查看经过Json组织的数据格式,我们将body打印,得到Json格式的数据如下:

红色框中的内容便是Json数据格式的内容,我们对其进行逐一介绍。

  • Json当中的每位数据对象都是使用{}形容的内容,一个{}表示一个对象;
  • Json当中每位对象中的数组是使用[]形容的内容,一个[]表示一个数组;
  • Json当中的字符串使用常规""形容的内容,一个""表示一个字符串;
  • Json当中的数字无论数据类型(整形和浮点型等),都是直接表示。

3.底层

了解Json使用之前,我们需要明白Json底层代码的实现逻辑。不用深究,只需要明白如何使用以及使用效果即可。

3.1数据对象表示

在Json当中的value.h当中,对[]和=进行了重载,于是我们便可以通过这两种运算符对Json格式数据当中内容进行赋值:

并且Json为我们提供了许多常用的接口,如下:

提供移除元素的removerMemvber接口:

提供添加元素的append接口:

提供获取元素个数的size接口:

 

提供转string的asString接口和转char *的asCstring接口:

以及提供转int、float和bool的asInt接口、asFloat接口和asBool接口: 

3.2序列化接口

首先是JSON_API StreamWriter当中的writer接口和实例化:

3.3反序列化接口

JSON_API CharReader当中的parse接口和实例化:

4.使用

在大致了解完Json的内容之后,我们可以结合上文中展示Json数据格式的代码,来对Json的使用进行一个示例展示,具体代码设计如下:

#include<iostream>
#include<string>
#include<memory>
#include<sstream>
#include<jsoncpp/json/json.h>

bool serialize(const Json::Value &root, std::string *out) {
    //Json::StreamWriter
    Json::StreamWriterBuilder swb;
    swb["commentStyle"] = "None";
    swb["indentation"] = "";
    std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
    std::stringstream ss;
    int ret = sw->write(root, &ss);
    if (ret != 0) {
        std::cerr << "serializer failed\n";
        return false;
    }
    *out = ss.str();
    return true;
}

bool unserialize(const std::string &out, Json::Value *root) {
    //Json::CharReader
    Json::CharReaderBuilder crb;
    std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
    std::string err;
    bool ret = cr->parse(out.c_str(), out.c_str() + out.size(), root, &err);
    if (ret == false) {
        std::cerr << err << std::endl;
        return false;
    }
    return true;
}

int main() {
    Json::Value root;
    root["id"] = 1;
    root["name"] = "张三";
    root["score"].append(77.7);
    root["score"].append(88.8);
    root["score"].append(99.9);

    std::string body;
    serialize(root, &body);
    std::cout << body << std::endl;
    Json::Value val;
    unserialize(body, &val);

    if (!val["id"].isNull())
        std::cout << "id:" << val["id"].asInt() << "\t";
    if (!val["name"].isNull())
        std::cout << "name:" << val["name"].asString() << "\t";
    if (!val["score"].isNull()) {
        std::cout << "score:";
        for (int i = 0; i < val["score"].size(); i++) {
            std::cout << val["score"][i].asFloat() << "\t"; 
        }
    }
        
    return 0;
}

从代码角度出发,我们先是定义Json数据格式的对象root,并对其进行赋值;然后定义body字符串,对Json类型数据root进行序列化之后保存到body当中,并打印查看Json格式下的数据内容;再定义val字符串,将Json类型数据root进行反序列化后保存val当中,并对val当中内容进行打印展示。

最后程序输出结果如下:

对于Json数据内容的打印,为便于展示我们对其进行了修改,取消了其中的换行和水平制表字符,所以显示打印结果在同一行。这也Json库提供的对外定义方式,在库中的定义如下:

 

在上述代码中定义的内容是:

是将换行取消,然后取消对象当中数据之间间隔。

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

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

相关文章

C++——缺省参数

缺省参数的定义 缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数的时候&#xff0c;如果没有指定实参&#xff0c;则采用该形参的缺省值&#xff0c;否则使用指定的实参。 void Func(int a 0) {cout << a << endl; } int main() { Func()…

并查集的原理与实现

1.概念 2.生活中的例子 小弟-老大&#xff1b; 帮派识别 3.实现 3.1 初始化 3.2 中间过程 3.3合并 3.4 并查集路径优化 直接把下面的节点指向最终的老大。 3.5 伪代码实现 3.6JAVA实现 findRoot: 谁是帮派的老大。例如山鸡的老大是陈浩南 connected: 我们是不是同一个大…

Golang服务的请求调度

文章目录 1. 写在前面2. SheddingHandler的实现原理3. 相关方案的对比4. 小结 1. 写在前面 最近在看相关的Go服务的请求调度的时候&#xff0c;发现在gin中默认提供的中间件中&#xff0c;不含有请求调度相关的逻辑中间件&#xff0c;去github查看了一些服务框架&#xff0c;发…

软工导论知识框架(八)面向对象设计风格

一.面向对象实现 把面向对象设计结果翻译成面向对象程序测试并调试面向对象的程序 二.程序设计语言 所有语言都可完成面向对象实现&#xff0c;但效果不同。 使用非面向对象语言编写面向对象程序&#xff0c;则必须由程序员自己把面向对象概念映射到目标程序中。 1.将来能够占…

Ubuntu常用配置

文章目录 1. 安装VMware虚拟机软件2. 下载Ubuntu镜像3. 创建Ubuntu虚拟机4. 设置屏幕分辨率5. 更改系统语言为中文6. 切换中文输入法7. 修改系统时间8. 修改锁屏时间9. 通过系统自带的应用商店安装软件10. 安装JDK11. 安装 IntelliJ IDEA12. 将左侧任务栏自动隐藏13. 安装docke…

用户数据报协议UDP

UDP的格式 载荷存放的是:应用层完整的UDP数据报 报头结构: 源端口号:发出的信息的来源端口目的端口号:信息要到达的目的端口UDP长度:2个字节(16位),即UDP总长度为:2^16bit 2^10bit * 2^6bit 1KB * 64 64KB.所以一个UDP的最大长度为64KBUDP校验和:网络的传输并非稳定传输,…

css3背景渐变

1.线性渐变 <style>.box {width: 200px;height: 200px;border: 1px solid black;float: left;margin-left: 50px;}.box1 {background-image: linear-gradient(green, yellow, red);}/* 右上 */.box2 {background-image: linear-gradient(to right top, green, yellow, re…

SAP MM学习笔记16-在库品目评价

在库品目评价是指评估物料。具体比如物料价格&#xff0c;数量&#xff0c;保管场所等发生变化的时候&#xff0c;判断是否发生了变化&#xff0c;要不要生成 FI票&#xff0c;用哪个FI科目来进行管理等内容就叫在库品目评价。 在库品目评价有很多层级&#xff0c;这里先讲3兄弟…

基于Qlearning强化学习的路径规划算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 Q值更新规则 4.2 基于Q-learning的路径规划算法设计 4.3 Q-learning路径规划流程 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022A 3.部分核心程序 ..…

Mybatis三剑客(一)在springboot中自动生成Mybatis【generator】

1、pom.xml中新增plugin <plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.7</version><configuration><overwrite>true</overwrite><…

分布式 - 服务器Nginx:一小时入门系列之动静分离

文章目录 1. 动静分离的好处2. 分离静态文件3. 修改 Nginx 配置文件4. location 命令修饰符优先级 1. 动静分离的好处 Apache Tocmat 严格来说是一款java EE服务器&#xff0c;主要是用来处理 servlet请求。处理css、js、图片这些静态文件的IO性能不够好&#xff0c;因此&…

IDEA关闭项目,但是后台程序没有关闭进程(解决方案)

最近遇到一个很奇怪的问题&#xff0c;idea关闭项目后&#xff0c;系统进程没有杀死进程&#xff0c;再次执行的时候会提示端口占用&#xff0c;并提示Process exited with an error: 1 (Exit value: 1) 错误原因&#xff1a;应用程序关闭后&#xff0c;进程不能同步关闭 解决方…

[vscode]vscode运行cmake时候exe不执行而且前面多一些字符

遇到一个奇怪问题,你单独打开cmd去执行vscode编译过程序没问题&#xff0c;但是你在vscode确不会执行&#xff0c;这是因为vscode没有读取到电脑环境变量导致加载DLL失败&#xff0c;但是在vscode终端不会给你提示少DLL&#xff0c;需要你自己把DLL复制到exe目录即可解决问题。…

关于Cesium的常见需求整理之点位和弹窗(点位弹窗)

一、点位上图 ①在Cesium中&#xff0c;每个自定义的地图元素被视为一个entity对象&#xff0c;如果我们要添加点位到地图上&#xff0c;那就必须先创建一个entity对象。 var entity new Cesium.Entity({position: position, });以上代码我们创建了一个entity对象&#xff0…

Python Opencv实践 - 图像缩放

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg_cat cv.imread("../SampleImages/cat.jpg", cv.IMREAD_COLOR) plt.imshow(img_cat[:,:,::-1])#图像绝对尺寸缩放 #cv.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) #指定Size大…

CANoe自动化工程的搭建

基于XMLCAPL建立自动化工程 1、导入ini文件2、新建 Test Environment3、报告类型4、代码编写 1、导入ini文件 工程的配置的文件&#xff0c;配置DUT相关信息&#xff0c;具体视工程而编写内容。 2、新建 Test Environment 1、新建XML测试用例环境 2、导入XML测试用例文件 …

关于Neo4j的使用及其基本命令

关于Neo4j的使用 文章目录 关于Neo4j的使用1、启动方式2、创建新节点&#xff0c;节点内有属性3、创建关系4、查询节点5、查询关系6、删除两个节点的关系7、删除节点8、删除某个标签的全部关系9、某个节点添加属性10、删除节点某个属性 1、启动方式 进入bin目录&#xff1a; …

Web 服务器 -【Tomcat】的简单学习

Tomcat1 简介1.1 什么是Web服务器 2 基本使用2.1 下载2.2 安装2.3 卸载2.4 启动2.5 关闭2.6 配置2.7 部署 3 Maven创建Web项目3.1 Web项目结构3.2 创建Maven Web项目 4 IDEA使用Tomcat4.1 集成本地Tomcat4.2 Tomcat Maven插件 Tomcat 1 简介 1.1 什么是Web服务器 Web服务器是…

Neo4j笔记-数据迁移(导出/导入)

这里先说明以下几点&#xff1a; Neo4j在4.0下版本默认的库名是&#xff1a;graph.db Neo4j在4.0上版本默认的库名是&#xff1a;neo4j.db 不管是Neo4j&#xff0c;还是Neo4j Desktop&#xff0c;都会在bin目录下有neo4j、neo4j-admin软件。在conf目录下&#xff0c;有neo4j.…

unity实现角色体力功能【体力条+体力计算】

导读&#xff1a;实现功能 1、角色体力计算 2、角色疲劳动画 3、体力条制作、跟随 默认做好角色的idle/run/walk动画、切换和玩家输入&#xff0c;我使用的是新输入系统&#xff0c;动画时单变量混合树&#xff0c;参数Sports。 【每一部分功能根据自己需求观看哦】 1、角色体…