Jsoncpp的安装与使用

news2024/12/24 9:53:35

目录

安装Jsoncpp

Jsoncpp的使用

Value类

构造函数

检测保存的数据类型

提取数据

对json数组的操作

对Json对象的操作 

FastWriter类 

Reader类


JsonCpp 是一个C++库,用于解析和生成JSON数据。它支持解析JSON文件或字符串到C++对象,以及将C++对象序列化回JSON格式。

安装Jsoncpp

我们可以输入以下命令安装jsoncpp库。

sudo yum install -y jsoncpp-devel

安装时默认安装动态库。头文件存储在 /usr/include/jsoncpp/json 中。

库文件存储在 /lib64 中,我们可以简单查看一下。

c56691039c7d423bace605b21904dc31.png

Jsoncpp的使用

对于 jsoncpp 我们只需要掌握三个类就可以覆盖开发时的绝大多数场景。

  • Json::Value

    • 这是 JsonCpp 中最核心的类,用于表示 JSON 值。Json::Value 可以包含任何 JSON 类型的数据:对象(一组键值对)、数组、字符串、数字、布尔值(true/false)、null 值。你可以使用这个类来创建、查询和修改 JSON 数据。
  • Json::Reader

    • Json::Reader 类用于解析 JSON 字符串。你可以使用这个类将一个符合 JSON 格式的字符串解析成一个 Json::Value 对象。这个过程称为 JSON 反序列化。
  • Json::Writer

    • Json::Writer  类用于将 Json::Value 对象转换回 JSON 字符串。这个过程称为 JSON 序列化。Json::Writer 还可以格式化 JSON 数据,使其以易于阅读的方式输出。

Jsoncpp库中的类定义在命名空间 Json 中 ,在使用时我们需要声明命名空间。

Json 支持以下类型:

nullValue

空值
intValue有符号整数
uintValue     无符号整数
realValue浮点数
stringValue字符串
booleanValue布尔数
arrayValue数组
objectValue键值对

Value类

Value 类是数据的容器,它支持存储Json中的所有类型。Value为我们提供了各种类型的构造函数。

构造函数

  • 默认构造函数:

    Json::Value value; //创建一个空的value对象
  • 构造一个具有特定类型的值:

    Json::Value value(1); // 整数 
    Json::Value value(1.0); // 浮点数 
    Json::Value value("string"); // 字符串 
    Json::Value value(true); // 布尔值
  • 构造一个数组或对象:

    Json::Value array(Json::arrayValue); // 空数组 
    Json::Value object(Json::objectValue);// 空对象
  • 复制构造函数:

    Json::Value value1; Json::Value value2(value1); // value2 是 value1 的副本
  • 构造一个具有特定值的数组或对象:

    Json::Value array(Json::arrayValue); // 明确指定数组类型 
    Json::Value object(Json::objectValue); // 明确指定对象类型
  • 构造一个包含初始值的数组或对象:

    Json::Value array(Json::arrayValue, 10); // 创建一个包含10个元素的数组,每个元素都是null
    Json::Value object(Json::objectValue, 5); // 创建一个包含5个元素的对象
  • 从另一个 JSON 值构造:

    Json::Value value1("initial value"); 
    Json::Value value2 = value1; // value2 是 value1 的副本

Jsoncpp也为我们提供了一系列的检测 Value 中存储的值。这些接口都很简单,从命名即可看出它们的作用,在此不过多介绍。

检测保存的数据类型

bool isNull() const;
bool isBool() const;
bool isInt() const;
bool isInt64() const;
bool isUInt() const;
bool isUInt64() const;
bool isIntegral() const;
bool isDouble() const;
bool isNumeric() const;
bool isString() const;
bool isArray() const;
bool isObject() const;

当我们从一个 Json::Value 对象中提取数据时,我们需要将它转换为相应的实际数据类型,同样Jsoncpp 为我们提供了相应的接口。

提取数据

// 将 Json::Value 对象转换为 int 类型。
Int asInt() const;
// 将 Json::Value 对象转换为 unsigned int 类型。
UInt asUInt() const;
// 将 Json::Value 对象转换为 int64_t 类型。
Int64 asInt64() const;
// 将 Json::Value 对象转换为 uint64_t 类型。
UInt64 asUInt64() const;
// 将 Json::Value 对象转换为最大的整数类型(long long 类型)。
LargestInt asLargestInt() const;
// 将 Json::Value 对象转换为最大的无符号整数类型(unsigned long long 类型)。
LargestUInt asLargestUInt() const;
// 将 Json::Value 对象转换为 std::string 类型。
JSONCPP_STRING asString() const;
// 将 Json::Value 对象转换为 float 类型。
float asFloat() const;
// 将 Json::Value 对象转换为 double 类型。
double asDouble() const;
// 将 Json::Value 对象转换为 bool 类型。
bool asBool() const;
// 将 Json::Value 对象转换为 C 风格的字符串(const char* 类型)。
const char* asCString() const;

在这些接口中,除了  asCString() 类型不匹配会返回空指针,其他接口在类型不匹配时都会则抛出 Json::TypeError。

这些接口都很简单,我们可以简单使用一下。

#include<jsoncpp/json/json.h>
#include<iostream>
using namespace Json;
int main()
{
    Value a(1234);
    if(a.isInt())
    {
        int b=a.asInt();
        std::cout << b << std::endl;
    }
    return 0;
}

因为 jsoncpp 是一个第三方库,所以编译时我们需要使用 -l 指定需要链接的库。

g++ -o test jsontest.cpp -ljsoncpp

8317f745cf4145beb25953e349e749bc.png

可以看到程序按预期输出 1234 。

对于Json数组 Value 同样有一系列接口。

对json数组的操作

Json数组可以存储Json支持的所有类型,包括数组。

ArrayIndex size() const;

返回数组时的大小,即数组中的元素数量。

Value& operator[](ArrayIndex index);
Value& operator[](int index);

重载的 [] 运算符,用于访问 Json::Value 对象作为数组时指定索引的元素。返回 Json::Value 对象的引用,允许修改。

const Value& operator[](ArrayIndex index) const;
const Value& operator[](int index) const;

重载的 [] 运算符,用于访问 Json::Value 对象作为数组时指定索引的元素。返回 Json::Value 对象的常量引用,不允许修改。

Value get(ArrayIndex index, const Value& defaultValue) const;

使用指定的 index 下标访问 Json::Value 对象中的元素。如果 index 在有效范围内,返回对应的 Json::Value 对象。如果 index 无效,返回提供的 defaultValue。

Value& append(const Value& value);

向数组的末尾添加一个新元素,并返回对新元素的引用。

const_iterator begin() const;

返回一个迭代器,指向 Json::Value 对象作为数组或对象的第一个元素。这个迭代器是 const_iterator 类型,只能用于读取元素。

const_iterator end() const;

返回一个迭代器,指向 Json::Value 对象数组或对象末尾的下一个位置。这个迭代器是 const_iterator 类型,表示迭代结束的位置。

#include<jsoncpp/json/json.h>
#include<iostream>
using namespace Json;
int main()
{
    Value arr(arrayValue);
    Value a(1);
    Value b("hello world");
    arr.append(a);
    arr.append(b);

    int x=arr[0].asInt();
    const char* y=arr[1].asCString();

    std::cout << "arr[0]:" << x << std::endl;
    std::cout << "arr[1]:" << y << std::endl; 
    return 0;
}
iterator begin();

返回一个迭代器,指向 Json::Value 对象作为数组或对象的第一个元素。这个迭代器是 iterator 类型,允许修改元素。

iterator end();

返回一个迭代器,指向 Json::Value 对象数组或对象末尾的下一个位置。这个迭代器是 iterator 类型,表示迭代结束的位置。

我们简单使用一下:

#include<jsoncpp/json/json.h>
#include<iostream>
using namespace Json;
int main()
{
    Value arr(arrayValue);
    Value a(1);
    Value b("hello world");
    arr.append(a);
    arr.append(b);

    int x=arr[0].asInt();
    const char* y=arr[1].asCString();

    std::cout << "arr[0]:" << x << std::endl;
    std::cout << "arr[1]:" << y << std::endl; 
    return 0;
}

运行结果: 

74b65fb4101e4f1b863e6ab6e37ca540.png

对Json对象的操作 

JSON 对象由一系列键值对组成,其中每个键都是一个字符串,与一个值关联。JSON 对象的键值对是无序的,这意味着键值对的顺序可能会在不同的 JSON 对象中有所不同,但它们表示相同的数据。同时JSON 对象中的每个键都是唯一的,不允许有重复的键。

添加键值对

obj["key1"] = "value1"; // 使用操作符 [] 添加键值对 obj["key2"] = 123; // 键可以关联不同类型的值

访问值

Json::Value value = obj["key1"]; // 获取键 "key1" 对应的值

检查键是否存在

if (obj.isMember("key1"))  // 键 "key1" 存在 

获取所有键的名称

Json::Value::Members members = obj.getMemberNames(); 
for (const auto& key : members) { std::cout << key << std::endl; }

Members是std::vector<std::string>的typedef别名。 

修改值

obj["key1"] = "new value"; // 修改已存在的键 "key1" 对应的值

删除键值对

obj.removeMember("key1"); // 删除键 "key1" 及其对应的值

检查 JSON 对象是否为空

bool isEmpty = obj.empty();

获取 JSON 对象的大小

Json::ArrayIndex size = obj.size(); // 返回对象中键值对的数量

我们简单演示一下使用。

#include<jsoncpp/json/json.h>
#include<iostream>
using namespace Json;
int main()
{
    Value obj(Json::objectValue);
    obj["age"]=18;
    obj["name"]="张三";
    Json::Value::Members members = obj.getMemberNames(); 
    for (const auto& key : members) 
    { 
        std::cout << key << std::endl; 
    }
    for (const auto &e : members)
    {
        std::cout << e << ":" << obj[e] << std::endl;
    }
    return 0;
}

我们运行一下。

945f369b48cf4c28ac0534a28e696477.png

Value也为我们提供了接口将对象序列化。

std::string toStyledString() const;

这个接口序列化出的字符串是带缩进与换行的,我们简单演示一下。

#include<jsoncpp/json/json.h>
#include<iostream>
#include<string>
using namespace Json;
int main()
{
    Value obj(Json::objectValue);
    obj["age"]=18;
    obj["name"]="张三";
    std::string s = obj.toStyledString();
    std::cout << s << std::endl;
    return 0;
}

 运行结果

ffe81d4de1374bd5ae38636a6db9c14c.png

 FastWriter类 

在 JsonCpp 中,FastWriter可以将 Json::Value 对象转换为 JSON 格式的字符串。与StyledStreamWriter 不同,FastWriter 不进行任何美化(不添加空格和缩进),因此通常会产生更紧凑的输出,但写入速度更快。在网络通信中,我们通常用它将数据序列化为单行,便于进行网络数据的传输。

std::string Json::FastWriter::write(const Value& root);

我们只需要掌握这一个接口即可,它会将传入的对象序列化为单行的字符串。

我们简单使用一下。

#include<jsoncpp/json/json.h>
#include<iostream>
#include<string>
using namespace Json;
int main()
{
    Value obj(Json::objectValue);
    obj["age"]=18;
    obj["name"]="张三";
    FastWriter writer;
    std::string s=writer.write(obj);
    std::cout << s ;
    return 0;
}

 运行结果:

689e28a79dc44ac6b0fa9af7aea16e54.png

Reader类

有序列化,就有反序列化,在将Json对象进行序列化后,我们可以通过 read 类进行反序列化,

bool Json::Reader::parse(const std::string& document,Value& root, bool collectComments = true);

参数:

  •  document: json格式字符串
  •  root: 传出参数, 存储了json字符串中解析出的数据
  •  collectComments: 是否保存json字符串中的注释信息默认true

parse有其他重载,但在这里我们不过多介绍。这里我们简单演示一下parse的使用

#include<jsoncpp/json/json.h>
#include<iostream>
#include<string>
using namespace Json;
int main()
{
    Value obj(Json::objectValue);
    obj["age"]=18;
    obj["name"]="张三";
    FastWriter writer;
    std::string s=writer.write(obj);
    std::cout << s ;
    Reader reader;
    Value val;
    reader.parse(s,val);
    std::cout << val["age"] << std::endl;
    std::cout << val["name"] << std::endl;
    return 0;
}

3d228721f2b44beca7e2704b7b4c13e7.png

 

 

 

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

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

相关文章

MySQL的安装—>Mariadb的安装(day21)

该网盘链接有效期为7天&#xff0c;有需要评论区扣我&#xff1a; 通过网盘分享的文件&#xff1a;mariadb-10.3.7-winx64.msi 链接: https://pan.baidu.com/s/1-r_w3NuP8amhIEedmTkWsQ?pwd2ua7 提取码: 2ua7 1 双击打开安装软件 本次安装的是mariaDB&#xff0c;双击打开mar…

SprinBoot+Vue学生选课微信小程序的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue3.6 uniapp代码 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平…

python进阶篇-day03-学生管理系统与深浅拷贝

day03-学生管理系统-面向对象 魔术方法: __ dict __将对象的属性和属性值封装为字典 用字典的值实例化对象: 对象名(**字典) > 拆包 student.py """ 该文件记录的是: 学生类的信息. ​ 学生的属性如下:姓名, 性别, 年龄, 联系方式, 描述信息 ""&…

单片机-STM32 ADC应用(五)

1.ADC模数转换 模拟数字转换器即A/D转换器&#xff0c;或简称ADC&#xff0c;通常是指一个将模拟信号转变为数字信号的电子元件。通常的模数转换器是将一个输入电压信号转换为一个输出的数字信号。由于数字信号本身不具有实际意义&#xff0c;仅仅表示一个相对大小。故任何一个…

STM32学习记录-11-RTC实时时钟

1 Unix时间戳 Unix 时间戳(Unix Timestamp)定义为从UTC/GMT的1970年1月1日0时0分0秒开始所经过的秒数,不考虑闰秒 时间戳存储在一个秒计数器中,秒计数器为32位/64位的整型变量 世界上所有时区的秒计数器相同,不同时区通过添加偏移来得到当地时间 2 UTC/GMT GMT(Green…

量化面试题:什么是朴素贝叶斯分类器?

朴素贝叶斯分类器是一种基于贝叶斯定理的简单而有效的分类算法。它的核心思想是利用特征之间的条件独立性假设来进行分类。以下是朴素贝叶斯分类器的几个关键点&#xff1a; 贝叶斯定理&#xff1a;朴素贝叶斯分类器基于贝叶斯定理&#xff0c;该定理描述了在已知某些条件下&a…

名城优企游学活动走进龙腾半导体:CRM助力构建营销服全流程体系

8月29日&#xff0c;由纷享销客主办的“数字中国 高效增长——名城优企游学系列活动之走进龙腾半导体”研讨会在西安市圆满落幕&#xff0c;来自业内众多领袖专家参与本次研讨会&#xff0c;深入分享交流半导体行业的数字化转型实践&#xff0c;探讨行业数字化、智能化转型之路…

华大智造 否极泰来

甲辰年开年至今&#xff0c;华大智造&#xff08;688114.SH&#xff09;经历了上市以来“最漫长的季节”。 仅在这半年多时间里&#xff0c;这家已经实现全球化布局且能排位在行业最前列的中国生命科技企业&#xff0c;遭遇了几乎所有能遭遇的不利局面。 宏观环境&#xff0c…

前端代码提交前的最后防线:使用Husky确保代码质量

需求背景 我们通常会引入ESLint和Prettier这样的工具来帮助我们规范本地代码的格式。然而&#xff0c;这种格式化过程仅在本地有效&#xff0c;并且依赖于我们在VSCode中手动设置自动保存功能。如果团队成员忘记进行这样的配置&#xff0c;或者在没有格式化的情况下提交了代码…

GIS地理信息+智慧巡检技术解决方案(Word原件)

1.系统概述 1.1.需求描述 1.2.需求分析 1.3.重难点分析 1.4.重难点解决措施 2.系统架构设计 2.1.系统架构图 2.2.关键技术 3.系统功能设计 3.1.功能清单列表 软件全套资料部分文档清单&#xff1a; 工作安排任务书&#xff0c;可行性分析报告&#xff0c;立项申请审批表&#x…

Datawhale X 李宏毅苹果书AI夏令营 Task1.2深度学习进阶详解

目录 一、批量梯度下降法&#xff08;Batch Gradient Descent&#xff0c;BGD&#xff09; 二、随机梯度下降法&#xff08;Stochastic Gradient Descent&#xff0c;SGD&#xff09; 三、动量法&#xff08;Momentum Method&#xff09; 四、自适应学习率的方法 五、并行…

微信小程序认证和备案

小程序备案的流程一般包括以下步骤‌&#xff1a; 准备备案所需材料‌&#xff1a;通常需要提供‌营业执照、法人的‌身份证、两个‌手机号和一个邮箱等资料。 ‌1 ‌登录‌微信公众平台‌&#xff1a;作为第一次开发微信小程序的服务商&#xff0c;需要通过微信公众平台申请…

JVM内存模型简述

JVM内存结构 虚拟机栈&#xff1a; 每个方法会在虚拟机栈中创建一个栈帧&#xff0c;存储这个方法的局部变量表&#xff0c;操作数栈&#xff0c;方法出口等信息。本地方法栈&#xff1a; 与虚拟机栈类似&#xff0c;只是虚拟机栈执行java方法&#xff0c;本地方法栈执行native…

工业园区智慧水务物联网平台建设方案

1. 项目背景与水资源现状 《工业园区智慧水务物联网平台建设方案》针对水资源分布不均、短缺严重的问题&#xff0c;提出了智慧水务物联网平台的建设方案&#xff0c;以应对漏损危害和提升水资源管理效率。 2. 水资源管理政策与目标 国家通过“水十条”和供水数据&#xff0…

基于yolov8的打架行为检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv8的打架行为检测系统&#xff0c;是当前公共安全领域的一项重要创新。YOLOv8作为最新的目标检测算法&#xff0c;以其高效、准确的性能&#xff0c;在各类图像和视频处理任务中表现出色。该系统利用YOLOv8的先进图像处理和机器学习算法框架&#xff0c;…

品牌知识产权维权的原因

在当今竞争激烈的商业环境中&#xff0c;品牌知识产权维权的重要性愈发凸显。品牌的价值不仅仅在于其产品或服务的质量&#xff0c;更在于其独特的标识、创新的技术以及丰富的文化内涵。而这些宝贵的资产&#xff0c;往往需要通过有效的知识产权保护来确保其安全。 品牌在发展的…

SI案例分享--考虑ESD保护二极管的差分线阻抗仿真

如下图所示&#xff0c;显示了利用CST电磁仿真软件构建的边沿耦合微带线的尺寸&#xff0c;按照 100 欧姆的差分线阻抗进行设计。由于差分线经常会通过连接器连接到电缆&#xff0c;因此极有可能发生 ESD 事件&#xff0c;该事件会在短时间内 &#xff08;< 1 ns&#xff09…

JS设计模式之“分即是合” - 建造者模式

引言 当我们在进行软件编程时&#xff0c;常常会遇到需要创建复杂对象的情况。这些对象可能有多个属性&#xff0c;属性之间存在依赖关系&#xff0c;或需要按照特定的骤来创建。在这种情况下&#xff0c;使用建造者模式&#xff08;Builder Pattern&#xff09;可以提供一种活…

搭建IPsec VPN隧道解决PLC设备与主控上位机无法使用公网IP进行通信的问题

问题描述 按照初设规定&#xff0c;每个工程点位都要安装一条具有独立公网IP的光纤专线&#xff0c;供该点位的视频监控设备、水质监测设备及PLC设备与外界进行通信。而在项目开发前期并没有意识到&#xff0c;组态软件(上位机)无法通过公网IP地址连接PLC&#xff0c;导致在交…

【网络原理】Udp 的报文结构,保姆式教学,快速入门

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…