Json简述(C++)

news2024/11/15 22:25:21

目录

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库提供的对外定义方式,在库中的定义如下:

 

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

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

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

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

相关文章

[RoarCTF 2019Online Proxy]sql巧妙盲注

文章目录 [RoarCTF 2019Online Proxy]sql巧妙盲注解题脚本脚本解析 [RoarCTF 2019Online Proxy]sql巧妙盲注 解题 在源代码界面发现&#xff1a;Current Ip 我们会联想到&#xff1a;X-Forwarded-For来修改ip&#xff1a; 结果我们发现&#xff0c;response会讲Last Ip回显出…

基于协同过滤的电影推荐

基于协同过滤的推荐算法综述 - 知乎 (zhihu.com) # -*- coding: gbk -*- import pandas as pd_userID 1#电影评分排序 ratings pd.read_csv(ml-latest-small/ratings.csv) #打印前20行 #print(ratings.head(10))#电影所属类别 movies pd.read_csv(ml-latest-small/movies.cs…

怎么做思维导图?试试这种绘制方法

怎么做思维导图&#xff1f;思维导图是一种非常实用的工具&#xff0c;可以帮助我们更好地整理思路、总结知识和规划方案。但是传统的手绘或电脑软件绘制思维导图的方法需要一定的时间和技能&#xff0c;对于想要快速制作思维导图的人来说可能不太方便。下面就给大家介绍一种在…

如何测试Linux磁盘的读写速度

在Linux系统中也有很多命令可以测试硬盘的读写速度指标。以下是几个常用命令&#xff08;注意&#xff1a;在执行测试命令之前&#xff0c;请务必备份数据以避免数据丢失&#xff01; 1、dd 命令 首先挂载磁盘 mount /dev/sdb /testdd 命令可用于进行硬盘读写速度测试。 例…

idea在控制台中输出文字显示乱码

VM options中加入下面这行 -Dfile.encodingutf-8

leetcode27—移除元素

思路&#xff1a; 参考26题目双指针的思想&#xff0c;只不过这道题不是快慢指针。 看到示例里面数组是无序的&#xff0c;也就是说后面的元素也是可能跟给定 val值相等的&#xff0c;那么怎么处理呢。就想到了从前往后遍历&#xff0c;如果left对应的元素 val时&#xff0c…

每日汇评:在50日移动均线下方,黄金的下行势

1、在美国周三公布通胀数据之前&#xff0c;金价可能会有所回升&#xff1b; 2、对中国通缩的担忧可能会限制金价反弹&#xff1b; 3、在每日技术面看跌的背景下&#xff0c;黄金价格仍处于“反弹后卖出”的状态&#xff1b; 金价从周二创下的一个月新低1923 美元开始大幅反…

go-zero 是如何实现计数器限流的?

原文链接&#xff1a; 如何实现计数器限流&#xff1f; 上一篇文章 go-zero 是如何做路由管理的&#xff1f; 介绍了路由管理&#xff0c;这篇文章来说说限流&#xff0c;主要介绍计数器限流算法&#xff0c;具体的代码实现&#xff0c;我们还是来分析微服务框架 go-zero 的源…

com.alibaba.fastjson.JSONObject循环给同一对象赋值会出现“$ref“:“$[0]“现象问题

文章目录 1、问题介绍2、如何解决fastjson中$ref对象重复引用问题3、举例说明 1、问题介绍 有些场景下&#xff0c;我们会选择用JSONObject代替Map来处理业务逻辑&#xff0c;但是使用JSONObject时有一个需要注意的地方&#xff1a;在处理JSONObject对象时&#xff0c;引用的c…

SpringBoot基础之注册Servlet三大组件

文章目录 前言一、介绍二、注入Bean2.1.ServletRegistrationBean2.2.FilterRegistrationBean2.3.ServletListenerRegistrationBean 三.演示结果总结 前言 本文章将介绍SpringBoot注册Servlet的三大组件 一、介绍 由于SpringBoot默认是以jar包的方式运行嵌入式Servlet容器来启…

【LangChain学习】基于PDF文档构建问答知识库(二)创建项目

这里我们使用到 fastapi 作为项目的web框架&#xff0c;它是一个快速&#xff08;高性能&#xff09;的 web 框架&#xff0c;上手简单。 一.创建 FastAPI 项目 我们在IDE中&#xff0c;左侧选择 FastAPI &#xff0c;右侧选择创建一个新的虚拟环境。 创建成功&#xff0c;会有…

UNIQUE VISION Programming Contest 2023 Summer(AtCoder Beginner Contest 312)D题题解

文章目录 [Count Bracket Sequences](https://atcoder.jp/contests/abc312/tasks/abc312_d)问题建模问题分析1.分析合法括号字符串的特点2.从集合角度分析字符串每个字符的作用代码 Count Bracket Sequences 问题建模 给定一个字符串&#xff0c;字符串内仅有3种字符&#xff…

期权定价模型系列【1】—BSM通用式模型

这是期权定价模型专栏的第一篇文章&#xff0c;此专栏旨在分享一些期权定价模型&#xff0c;将会从最基础的BSM模型开始写起&#xff0c;逐步扩散到蒙特卡洛模拟、二叉树等数值法模型&#xff0c;以及跳跃扩散模型、随机波动率模型&#xff0c;神经网络模型等等。 如果你觉得有…

[OnWork.Tools]系列 05-系统工具

简介 系统工具主要是将Window常用工具的快捷启动的集合 双击快速启动 计算器,记事本,截图,画图工具 控制面板,服务管理,关闭显示器,关机 启动文件夹,我的电脑,管理工具 右键菜单 添加快捷方式到桌面

外卖点餐小程序开源源码——支持扫码点餐

一套支持店内扫码点餐、外卖点餐配送于一体的餐饮系统&#xff0c;支持商家创建优惠券&#xff0c;支持商家自定义打印机功能&#xff0c;支持商家财务管理&#xff0c;支持商户菜品管理&#xff0c;支持菜品自定义分类&#xff0c;支持商家招募骑手入驻功能。系统基于thinkphp…

类与对象【下】

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析2 目录 &#x1f449;&#x1f3fb;初始化列表初始化列表注意点 &#x1f449;&#x1f…

LinearAlgebraMIT_7_Ax=0

上节课讲了向量子空间中的列空间和零空间&#xff0c;这节课来讲零空间的(Special solutions)特解&#xff0c;也就是Ax0的特解。在求解特解的核心便是使用消元法求得(row echelon form)阶梯矩阵或者(reduced row echelon form/RREF)最简矩阵。 我们接下来举一个例子&#xff…

Android使用kotlin+协程+room数据库的简单应用

前言&#xff1a;一般主线程&#xff08;UI线程&#xff09;中是不能执行创建数据这些操作的&#xff0c;因为等待时间长。所以协程就是为了解决这个问题出现。 第一步&#xff1a;在模块级的build.gradle中引入 id com.android.application// roomid kotlin-androidid kotlin…

亚马逊第三方卖家服务收入已达自营81%

据MarketplacePulse最新报道&#xff0c;亚马逊在第三方卖家服务上的收入&#xff0c;已经达到相当于其自营业务81%的规模。 佣金、物流费用以及广告构成了亚马逊整个第三方卖家服务。亚马逊最新发布的第二季度财报显示&#xff0c;亚马逊在包括销售佣金、物流费用的第三方卖…