JSON与Jsoncpp库:数据交换的灵活选择

news2024/9/20 5:33:41

目录

引言

一.JSON简介

二. Jsoncpp库概述

三. Jsoncpp核心类介绍

3.1 Json::Value类

3.2 序列化与反序列化类

四. 实现序列化

五. 实现反序列化

结语


引言

在现代软件开发中,数据交换格式扮演着至关重要的角色。JSON(JavaScript Object Notation)以其简洁、易于阅读和支持多种数据类型的特点,成为了数据交换领域的明星。本文将深入探讨JSON的基本概念、数据类型以及如何使用Jsoncpp库实现JSON的序列化与反序列化。

一.JSON简介

JSON是一种轻量级的数据交换格式,它基于文本,易于人阅读和编写,同时也易于机器解析和生成。JSON的数据结构包括以下几种:

  • 对象:由花括号{}包围,存储键值对。
  • 数组:由中括号[]包围,存储有序集合。
  • 字符串:由双引号""包围。
  • 数字:整数或浮点数。
  • 布尔值truefalse
  • null:表示空值。
例:⼩明同学的学⽣信息
char name = "⼩明";
int age = 18;
float score[3] = {88.5, 99, 58};
则json这种数据交换格式是将这多种数据对象组织成为⼀个字符串:
[
 {
 "姓名" : "⼩明",
 "年龄" : 18,
 "成绩" : [88.5, 99, 58]
 },
 {
 "姓名" : "⼩⿊",
 "年龄" : 18,
 "成绩" : [88.5, 99, 58]
 }
]

二. Jsoncpp库概述

Jsoncpp是一个流行的C++库,用于处理JSON数据。它提供了序列化和反序列化的机制,使得在C++程序中生成和解析JSON数据变得简单。

三. Jsoncpp核心类介绍

// Json数据对象类
class Json::Value
{
	Value &operator=(const Value &other); // Value重载了[]和=,因此所有的赋值和获取数据都可以通过
	Value &operator[](const std::string &key); // 简单的⽅式完成 val["姓名"] = "⼩明 ";
	Value &operator[](const char *key);
	Value removeMember(const char *key);			 // 移除元素
	const Value &operator[](ArrayIndex index) const; // val["成绩"][0]
	Value &append(const Value &value);				 // 添加数组元素val["绩"].append(88);
	ArrayIndex size() const;						 // 获取数组元素个数 val["绩"].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
	bool asBool() const;   // 转 bool
};
// json序列化类,低版本⽤这个更简单
class JSON_API Writer
{
	virtual std::string write(const Value &root) = 0;
} 
class JSON_API FastWriter : public Writer
{
	virtual std::string write(const Value &root);
} 
class JSON_API StyledWriter : public Writer
{
	virtual std::string write(const Value &root);
}
// json序列化类,⾼版本推荐,如果⽤低版本的接⼝可能会有警告
class JSON_API StreamWriter
{
	virtual int write(Value const &root, std::ostream *sout) = 0;
} 
class JSON_API StreamWriterBuilder : public StreamWriter::Factory
{
	virtual StreamWriter *newStreamWriter() const;
}
// json反序列化类,低版本⽤起来更简单
class JSON_API Reader
{
	bool parse(const std::string &document, Value &root, bool collectComments = true);
}
// json反序列化类,⾼版本更推荐
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;
}

3.1 Json::Value类

Json::Value类是Jsoncpp中表示JSON数据的核心类。它提供了一系列的方法来操作JSON数据:

  • operator[]:通过键名或数组索引访问数据。
  • asStringasIntasFloatasBool:将JSON数据转换为相应的C++数据类型。
  • append:向JSON数组中添加元素。

3.2 序列化与反序列化类

序列化是将JSON对象转换为字符串的过程,反序列化则是相反的过程。Jsoncpp提供了以下类来实现这些功能:

  • StreamWriterStreamWriterBuilder:用于创建序列化器,将Json::Value对象转换为JSON格式的字符串。
  • CharReaderCharReaderBuilder:用于创建反序列化器,将JSON格式的字符串解析为Json::Value对象。

四. 实现序列化

下面是一个使用Jsoncpp实现序列化的示例:

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

int main() {
    const char* name = "小明";
    int age = 19;
    float score[] = {77.5, 88, 99.5};
    Json::Value val;
    val["姓名"] = name;
    val["年龄"] = age;
    val["成绩"] = Json::Value(Json::arrayValue);
    for (float s : score) {
        val["成绩"].append(s);
    }

    Json::StreamWriterBuilder swb;
    std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
    std::stringstream ss;

    // 检查sw是否为空指针
    if (!sw) {
        std::cerr << "Failed to create StreamWriter" << std::endl;
        return -1;
    }

    try {
        int result = sw->write(val, &ss);
        if (result != 0) {  // 检查是否有错误
            std::cerr << "Write failed with error code: " << result << std::endl;
        } else {
            std::cout << ss.str() << std::endl;
        }
    } catch (const std::exception& e) {
        std::cerr << "Exception occurred: " << e.what() << std::endl;
        return -1;
    }

    return 0;
}

五. 实现反序列化

下面是一个使用Jsoncpp实现反序列化的示例:

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

int main()
{
    std::string str = R"({"姓名":"小明", "年龄":18, "成绩":[76.5, 55, 88]})";
    Json::Value root;
    Json::CharReaderBuilder crb;
    std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
    std::string err;
    if (!cr->parse(str.c_str(), str.c_str() + str.size(), &root, &err))
    {
        std::cout << "Parse error: " << err << std::endl;
    }
    else
    {
        std::cout << "Name: " << root["姓名"].asString() << std::endl;
        std::cout << "Age: " << root["年龄"].asInt() << std::endl;
        int sz = root["成绩"].size();
        for (int i = 0; i < sz; i++)
        {
            std::cout << "Score: " << root["成绩"][i].asFloat() << std::endl;
        }
    }
    return 0;
}

结语

JSON作为一种灵活的数据交换格式,结合Jsoncpp库,为C++开发者提供了强大的数据交换能力。无论是网络通信还是数据存储,JSON和Jsoncpp都是你的理想选择。通过本文的介绍,希望你能对JSON和Jsoncpp有一个全面的了解,并能将其应用到实际开发中。

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

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

相关文章

鸿蒙(API 12 Beta3版)【媒体会话提供方】本地媒体会话

音视频应用在实现音视频功能的同时&#xff0c;需要作为媒体会话提供方接入媒体会话&#xff0c;在媒体会话控制方&#xff08;例如播控中心&#xff09;中展示媒体相关信息&#xff0c;及响应媒体会话控制方下发的播控命令。 基本概念 媒体会话元数据&#xff08;AVMetadata…

WordPress原创插件:Download-block-plugin下载按钮图标美化

WordPress原创插件&#xff1a;Download-block-plugin下载按钮图标美化 https://download.csdn.net/download/huayula/89632743

Mapreduce_csv_averageCSV文件计算平均值

csv文件求某个平均数据 查询每个部门的平均工资&#xff0c;最后输出 数据处理过程 employee_noheader.csv&#xff08;没做关于首行的处理&#xff0c;运行时请自行删除&#xff09; EmployeeID,EmployeeName,DepartmentID,Salary 1,ZhangSan,101,5000 2,LiSi,102,6000…

疫情下图书馆管理系统

TOC springboot126疫情下图书馆管理系统 系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管…

mock.js的简单使用~

1、什么是mock? mock.js:是一款模拟数据生成器&#xff0c;可以生成随机数据&#xff0c;拦截 Ajax 请求. 2、mock的作用。 可以通过mock来模拟后端接口&#xff0c;可随机生成所需数据&#xff0c;模拟对数据的增删改查。并且截Ajax请求不需要修改既有代码就可以拦截&…

RCE-eval长度限制突破技巧

目录 一、长度17的限制绕过 1、最简单的绕过 &#xff08;一&#xff09;绕过 &#xff08;二&#xff09;编写一句话木马 2、文件包含的利用 &#xff08;一&#xff09;远程文件包含的利用 &#xff08;二&#xff09;本地文件包含的利用 3、usort绕过 &#xff08…

BGP路由优选(五)

当到达同一个目的网段存在多条路由时&#xff0c;BGP通过如下的次序进行路由优选&#xff1a; 丢弃下一跳不可达的路由。 优选Preferred-Value属性值最大的路由。优选Local_Preference属性值最大的路由。本地始发的BGP路由优于从其他对等体学习到的路由&#xff0c;本地始发的路…

使用腾讯云存储桶COS来实现上传和下载图片功能

有个需求&#xff0c;需要上传和下载图片&#xff0c;我决定使用腾讯云存储桶来做服务器存储目录&#xff0c;供程序上传和下载使用。 1、首先打开对应网站&#xff1a;云产品免费体验馆_云产品免费试用_个人云产品试用-腾讯云&#xff0c;点击左边的"存储"项&#x…

proxy负载均衡

endpoint &#xff1a; 终点、终端 看service服务器的ip kubectl get ep backend -> real server &#xff1a;真正提供web服务的服务器 负载均衡器 load balancer --》LB USER -->LB --->BACKEND(real server) nginx SERVICE --->很多的endpoint--》po…

报名表EXCEL图片批量下载源码-CyberWinApp-SAAS 本地化及未来之窗行业应用跨平台架构

每次报名表都会包含大量照片&#xff0c;一张一张下载很慢 可以通过未来之窗开源平台架构 开开excel批量下载 实现代码也很简单 function 未来之窗下载(){ let 未来之窗地址 document.getElementById("batchurl").value; let 保存路径 document.getElementById(…

GD32 MCU如何使用双ADC内核提高ADC采样率?

如下图所示&#xff0c;GD32F303系列MCU在不同的ADC位宽情况下均具有对应的最高采样率&#xff0c;那这个最高采样率还可以提高吗&#xff1f; 答案是可以的。GD32F30X系列MCU可以支持双ADC内核&#xff0c;分别为ADC0和ADC1&#xff0c;且双ADC可以支持同步模式&#xff0c;同…

力扣热题100_链表_206_反转链表

文章目录 题目链接解题思路解题代码 题目链接 206. 反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 示例 2&#xff1a; 输入&#xf…

Leetcode面试经典150题-146.LRU缓存

解法都在代码里&#xff0c;不懂就留言或者私信&#xff0c;这个题大概率不会让你直接写代码&#xff0c;而是说以下思路&#xff0c;如果写代码这个题写出来基本就过了 class LRUCache {/**首先我们得有缓存&#xff0c;get和put都是O(1)时间复杂度&#xff0c;我们常用的数…

公用事业公司与数据中心的电力协议推动未来增长

随着人工智能技术的迅猛发展&#xff0c;美国公用事业公司正在积极与数据中心运营商签订电力供应协议。这一趋势预计将显著提升这些公司的销售额和利润&#xff0c;并对未来几年的能源市场产生深远影响。 数据中心电力需求激增 根据高盛的报告&#xff0c;到2030年&#xff0c…

WMS助力企业数字化转型(六)

在当今数字化时代&#xff0c;仓库管理系统&#xff08;WMS&#xff09;作为推动企业数字化转型的重要工具&#xff0c;通过实时数据监控、自动化操作和智能分析&#xff0c;大幅提升了仓储管理的效率与精准度&#xff0c;为企业在供应链优化、库存控制和客户满意度方面带来了显…

Datawhale X 魔搭 AI夏令营 第四期魔搭-AIGC文生图方向Task2笔记

了解一下 AI生图技术 的能力&局限 对所有人来说&#xff0c;定期关注AI生图的最新能力情况都十分重要&#xff1a; 对于普通人来说&#xff0c;可以避免被常见的AI生图场景欺骗&#xff0c;偶尔也可以通过相关工具绘图 对于创作者来说&#xff0c;通过AI生图的工具可以快速…

GUI Agent with SFT 学习

grounding指的是基础训练&#xff0c;定位之类的意思&#xff0c;sft指的是监督微调&#xff0c;也就是用带有标签的数据集对与训练完毕的模型进行微调&#xff08;因为是带标签的&#xff0c;所以叫监督&#xff09; ui理解能力分为两个部分&#xff1a;Static UI understandi…

离线安装部署springboot+vue系统到服务器

注意&#xff1a;首先服务器会有多个网卡&#xff0c;这些服务器的网卡连接所需要的文件可能不是我们默认的ifcfg-eth0/ifcfgens33,可以试着切换一下服务器网线插入的接口&#xff0c;要保证服务器网线插入的接口和网卡对应的文件一致 说明&#xff0c;在一些政府&#xff08;保…

lvs的相关应用2

lvs 安装lvs 配置规则&#xff0c;查看所有的规则&#xff0c;如果已经配置好规则&#xff0c;重启之后就没了 [rootds01 ~]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forwa…

react的setState中为什么不能用++?

背景&#xff1a; 在使用react的过程中产生了一些困惑&#xff0c;handleClick函数的功能是记录点击次数&#xff0c;handleClick函数被绑定到按钮中&#xff0c;每点击一次将通过this.state.counter将累计的点击次数显示在页面上 困惑&#xff1a; 为什么不能直接写prevStat…