JsonCpp:更简洁的序列化及反序列化

简介

  • jsoncpp 提供了一组简单易用的 API,使得在 C++ 程序中处理 JSON 数据变得更加方便和高效。

安装

  • linux环境下安装jsoncpp
sudo apt-get update
sudo apt-get install --reinstall libjsoncpp-dev
  • 建立软链接确保编译器找到头文件 #include <json/json.h>
sudo ln -s /usr/include/jsoncpp/json /usr/include/json

简易demo: 基础数据读写

json数据的序列化及反序列化

/* example.cpp */ 
#include <iostream>
#include <fstream>
#include <json/json.h> // JSONcpp 头文件bool writeJsonToFile(const std::string &filename)
{// 创建一个 JSON 对象Json::Value root;root["key"] = "item";root["value1"] = 10;root["value2"] = 1.2345f;root["value3"] = 2.3456f;// 将 JSON 对象转换为字符串Json::StreamWriterBuilder builder;std::string jsonString = Json::writeString(builder, root);// 将 JSON 字符串写入文件std::ofstream ofs(filename);if (!ofs.is_open()){std::cerr << "Failed to open file for writing: " << filename << std::endl;return false;}ofs << jsonString;ofs.close();std::cout << "JSON data written to file: " << filename << std::endl;return true;
}bool readAndParseJsonFile(const std::string &filename)
{// 打开文件并读取 JSON 数据std::ifstream ifs(filename);if (!ifs.is_open()){std::cerr << "Failed to open file for reading: " << filename << std::endl;return false;}Json::Value root;Json::CharReaderBuilder readerBuilder;std::string errs;// 解析 JSON 数据if (!Json::parseFromStream(readerBuilder, ifs, &root, &errs)){std::cerr << "Failed to parse JSON in file: " << filename << std::endl;std::cerr << errs << std::endl;return false;}// 获取 JSON 中的字段值std::string key = root["key"].asString();int value1 = root["value1"].asInt();float value2 = root["value2"].asFloat();double value3 = root["value3"].asDouble();// 打印解析后的值std::cout << "key: " << key << std::endl;std::cout << "value1: " << value1 << std::endl;std::cout << "value2: " << value2 << std::endl;std::cout << "value3: " << value3 << std::endl;return true;
}int main()
{const std::string filename = "example.json";// 写入 JSON 数据到文件if (!writeJsonToFile(filename)){return 1;}// 从文件读取并解析 JSON 数据if (!readAndParseJsonFile(filename)){return 1;}return 0;
}
  • 编译时需链接jsoncpp库
g++ example.cpp -o example -ljsoncpp
  • result
    在这里插入图片描述

升级demo: 有层级的数据结构, 包括结构体、数组

#include <iostream>
#include <fstream>
#include <vector>
#include <json/json.h> // JSONcpp 头文件struct SecurityConfig
{std::string username;std::string password;
};struct ServerConfig
{std::string address;int port;int timeout;SecurityConfig securityConfig;
};struct FeatureFlags
{bool enableFeature;
};bool writeConfigToFile(const std::string &filename, const ServerConfig &serverConfig, const std::vector<FeatureFlags> &featureFlagsList)
{// 创建一个 JSON 对象Json::Value root;// 构建服务器配置节点Json::Value serverNode;serverNode["address"] = serverConfig.address;serverNode["port"] = serverConfig.port;serverNode["timeout"] = serverConfig.timeout;// 构建安全配置节点Json::Value securityNode;securityNode["username"] = serverConfig.securityConfig.username;securityNode["password"] = serverConfig.securityConfig.password;serverNode["securityConfig"] = securityNode;root["server"] = serverNode;// 构建功能开关配置节点数组Json::Value featuresArray(Json::arrayValue);for (const auto &flags : featureFlagsList){Json::Value featureNode;featureNode["enableFeature"] = flags.enableFeature;featuresArray.append(featureNode);}root["featureFlags"] = featuresArray;// 将 JSON 对象转换为字符串Json::StreamWriterBuilder builder;std::string jsonString = Json::writeString(builder, root);// 将 JSON 字符串写入文件std::ofstream ofs(filename);if (!ofs.is_open()){std::cerr << "Failed to open file for writing: " << filename << std::endl;return false;}ofs << jsonString;ofs.close();std::cout << "JSON data written to file: " << filename << std::endl;return true;
}bool readConfigFromFile(const std::string &filename, ServerConfig &serverConfig, std::vector<FeatureFlags> &featureFlagsList)
{// 打开文件并读取 JSON 数据std::ifstream ifs(filename);if (!ifs.is_open()){std::cerr << "Failed to open file: " << filename << std::endl;return false;}// 解析 JSON 数据Json::Value root;Json::CharReaderBuilder readerBuilder;std::string errs;if (!Json::parseFromStream(readerBuilder, ifs, &root, &errs)){std::cerr << "Failed to parse JSON in file: " << filename << std::endl;std::cerr << errs << std::endl;return false;}// 解析服务器配置if (root.isMember("server")){Json::Value serverNode = root["server"];serverConfig.address = serverNode["address"].asString();serverConfig.port = serverNode["port"].asInt();serverConfig.timeout = serverNode["timeout"].asInt();// 解析安全配置if (serverNode.isMember("securityConfig")){Json::Value securityNode = serverNode["securityConfig"];serverConfig.securityConfig.username = securityNode["username"].asString();serverConfig.securityConfig.password = securityNode["password"].asString();}else{std::cerr << "Missing 'securityConfig' in JSON file." << std::endl;return false;}}else{std::cerr << "Missing 'server' configuration in JSON file." << std::endl;return false;}// 解析功能开关配置数组if (root.isMember("featureFlags")){Json::Value featuresArray = root["featureFlags"];if (featuresArray.isArray()){for (const auto &featureNode : featuresArray){FeatureFlags flags;flags.enableFeature = featureNode["enableFeature"].asBool();featureFlagsList.push_back(flags);}}else{std::cerr << "'featureFlags' is not an array in JSON file." << std::endl;return false;}}else{std::cerr << "Missing 'featureFlags' configuration in JSON file." << std::endl;return false;}return true;
}int main()
{const std::string filename = "config.json";ServerConfig serverConfig = {"127.0.0.1", 8080, 5000, {"admin", "password"}};std::vector<FeatureFlags> featureFlagsList = {{true},{false},{true}};// 将配置写入 JSON 文件if (!writeConfigToFile(filename, serverConfig, featureFlagsList)){return 1;}std::cout << "Configuration written to file: " << filename << std::endl;// 从文件读取并解析 JSON 配置数据ServerConfig readServerConfig;std::vector<FeatureFlags> readFeatureFlagsList;if (!readConfigFromFile(filename, readServerConfig, readFeatureFlagsList)){return 1;}// 打印读取的配置信息std::cout << "Server Configuration:" << std::endl;std::cout << "  Address: " << readServerConfig.address << std::endl;std::cout << "  Port: " << readServerConfig.port << std::endl;std::cout << "  Timeout: " << readServerConfig.timeout << " ms" << std::endl;std::cout << "  Security Config:" << std::endl;std::cout << "    Username: " << readServerConfig.securityConfig.username << std::endl;std::cout << "    Password: " << readServerConfig.securityConfig.password << std::endl;std::cout << "Feature Flags:" << std::endl;for (size_t i = 0; i < readFeatureFlagsList.size(); ++i){std::cout << "  Feature " << i + 1 << " Enabled: " << (readFeatureFlagsList[i].enableFeature ? "true" : "false") << std::endl;}return 0;
}
  • result
    在这里插入图片描述

节点不存在的情况

  • 节点不存在的情况会解析出默认的数据 如0或空字符串
  • 主动判断节点是否存在:
    // 访问不存在的节点if (root.isMember("database")){// 这里的条件不会满足,因为 JSON 文件中没有 "database" 节点Json::Value dbNode = root["database"];// 如果不存在的节点,会得到默认值std::string dbName = dbNode["name"].asString(); // 返回空字符串 ""int dbPort = dbNode["port"].asInt();            // 返回默认的整数值 0std::cout << "Database Name: " << dbName << std::endl;std::cout << "Database Port: " << dbPort << std::endl;}else{std::cerr << "Missing 'database' configuration in JSON file." << std::endl;}

附件

  • josncpp源码
    https://github.com/open-source-parsers/jsoncpp
  • 文档
    https://open-source-parsers.github.io/jsoncpp-docs/doxygen/files.html

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue原生写全选反选框

效果 场景&#xff1a;Vue全选框在头部&#xff0c;子框在v-for循环内部。 实现&#xff1a;点击全选框&#xff0c;所有子项选中&#xff0c;再次点击取消&#xff1b;子项全选中&#xff0c;全选框自动勾选&#xff0c;子项并未全选&#xff0c;全选框不勾选&#xff1b;已选…

LVM核心概念

1. LVM简介 LVM是逻辑盘卷管理&#xff08;Logical Volume Manager&#xff09;的简称&#xff0c;它是Linux环境下对磁盘分区进行管理的一种机制&#xff0c;LVM是建立在硬盘和分区之上的一个逻辑层&#xff0c;来提高磁盘分区管理的灵活性。 优点&#xff1a; 可以灵活分配…

大数据学习之Clickhouse

Clickhouse-23.2.1.2537 学习 一、Clickhouse概述 clickhouse 官网网址&#xff1a;https://clickhouse.com/ ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS)。 OLTP(联机事务处理系统)例如mysql等关系型数据库&#xff0c;在对于存储小数据量的时候&#xff…

Langchain-Chatchat本地部署记录,三分钟学会!

1.前言&#xff1a; 最近AI爆发式的火&#xff0c;忆往昔尤记得16,17那会移动互联网是特别火热的&#xff0c;也造富了一批公司和个人&#xff0c;出来了很多精妙的app应用。现在轮到AI发力了&#xff0c;想想自己也应该参与到这场时代的浪潮之中&#xff0c;所以就找了开源的…

【TB作品】atmega16 计算器,ATMEGA16单片机,Proteus仿真

实验报告&#xff1a;基于ATmega16单片机的简易计算器设计 1. 实验背景 计算器是日常生活和工作中不可或缺的工具&#xff0c;通过按键输入即可实现基本的四则运算。通过本实验&#xff0c;我们将利用ATmega16单片机、矩阵键盘和LCD1602显示屏&#xff0c;设计并实现一个简易…

一招解决 | IP地址访问怎么实现https

没有域名的情况下&#xff0c;使用IP地址实现HTTPS访问是可以的&#xff0c;但相比使用域名会有些许限制&#xff0c;需要通过部署专用于IP地址的SSL/TLS证书来实现。 IP地址实现HTTPS访问的过程与使用域名类似&#xff0c;但有几个关键的区别。以下是使用IP地址实现HTTPS访问…

Win10 电脑屏幕保护怎么设置?学会了你也能轻松设置屏保

在 Windows 10 操作系统中&#xff0c;屏幕保护程序不仅能够为您的电脑增添个性化色彩&#xff0c;还能在长时间不操作电脑时保护屏幕免受烧屏影响。下面是一份详细指南&#xff0c;简鹿办公编辑教您如何通过 Windows 搜索框设置屏幕保护程序&#xff0c;并调整相关参数&#x…

uniapp——上传图片获取到file对象而非临时地址——基础积累

最近在看uniapp的代码&#xff0c;遇到一个需求&#xff0c;就是要实现上传图片的功能 uniapp 官网地址&#xff1a;https://uniapp.dcloud.net.cn/ 上传图片有对应的API&#xff1a; uni.chooseImage方法&#xff1a;https://uniapp.dcloud.net.cn/api/media/image.html#choo…

使用uniapp编写微信小程序

使用uniapp编写微信小程序 文章目录 使用uniapp编写微信小程序前言一、项目搭建1.1 创建项目方式1.1.1 HBuilderX工具创建1.1.2 命令行下载1.1.3 直接Gitee下载 1.2 项目文件解构1.2.1 安装依赖1.2.2 项目启动1.2.3 文件结构释义 1.2 引入uni-ui介绍 二、拓展2.1 uni-app使用uc…

“探索价值增长消费:让每一笔购物都成为增值之旅“

亲爱的顾客们&#xff0c;你们好&#xff01;今天&#xff0c;我将带你们探索一种革命性的消费哲学——价值增长消费&#xff0c;让每一次购物都成为一次增值之旅&#xff01; 在传统消费观念里&#xff0c;我们付出金钱换取商品或服务&#xff0c;随后这些便成为过去。但如今…

2024 年江西省研究生数学建模竞赛题目 B题投标中的竞争策略问题---完整文章分享(仅供学习)

问题&#xff1a; 招投标问题是企业运营过程中必须面对的基本问题之一。现有的招投标平台有国家级的&#xff0c;也有地方性的。在招投标过程中&#xff0c;企业需要全面了解招标公告中的相关信息&#xff0c;在遵守招投标各种规范和制度的基础上&#xff0c;选择有效的竞争策…

【AI绘画Stable Diffusion】教你制作 SD 光影文字,保姆级教程建议收藏!(附模型下载)

大家好&#xff0c;我是设计师阿威 最近光影文字又开始火起来了。今天讲讲怎么利用 Stable Diffusion 的 ControlNet 插件来制作光影图片。 1.下载光影模型组件 1.SD主模型&#xff1a;majicMIX realistic V6、xxmix9realistic_v26 2. ControlNet 的模型&#xff1a;Bright…

CV每日论文--2024.6.28

1、On Scaling Up 3D Gaussian Splatting Training 中文标题&#xff1a;扩展 3D 高斯泼溅训练 简介&#xff1a;3D高斯点描(3DGS)由于其卓越的视觉质量和渲染速度,越来越受欢迎用于3D重建。然而,3DGS的训练目前仅在单个GPU上进行,由于内存限制,它的处理高分辨率和大规模3D重建…

【海思Hi3403V100】多目拼接相机套板硬件规划方案

海思Hi3403V100 是专业超高清智能网络摄像头 SoC。该芯片最高支持四路 sensor 输入&#xff0c;支持最高 4K60fps 的 ISP 图像处理能力&#xff0c;支持 3F 、WDR、多级降噪、六轴防抖、硬件拼接、多光谱融合等多种传统图像增强和处理算法&#xff0c;支持通过AI 算法对输入图像…

【Qwen2部署实战】Qwen2初体验:用Transformers打造智能聊天机器人

系列篇章&#x1f4a5; No.文章1【Qwen部署实战】探索Qwen-7B-Chat&#xff1a;阿里云大型语言模型的对话实践2【Qwen2部署实战】Qwen2初体验&#xff1a;用Transformers打造智能聊天机器人3【Qwen2部署实战】探索Qwen2-7B&#xff1a;通过FastApi框架实现API的部署与调用4【Q…

windows USB 驱动开发-URB结构

通用串行总线 (USB) 客户端驱动程序无法直接与其设备通信。 相反&#xff0c;客户端驱动程序会创建请求并将其提交到 USB 驱动程序堆栈进行处理。 在每个请求中&#xff0c;客户端驱动程序提供一个可变长度的数据结构&#xff0c;称为 USB 请求块 (URB) &#xff0c;URB 结构描…

从理论到实践的指南:企业如何建立有效的EHS管理体系?

企业如何建立有效的EHS管理体系&#xff1f;对于任何企业&#xff0c;没有安全就谈不上稳定生产和经济效益&#xff0c;因此建立EHS管理体系是解决企业长期追求的建立安全管理长效机制的最有效手段。良好的体系运转&#xff0c;可以最大限度地减少事故发生。 这篇借着开头这个…

年轻人「入侵」厂货电商:泼天的富贵or甜蜜的烦恼?

【潮汐商业评论/原创】 “明天我们带个黑色塑料袋&#xff0c;假装是批发拿货的&#xff0c;看看能不能淘到好货。这个批发‘黑话’你也学一下&#xff0c;别到时候露馅。” Paula正兴冲冲地跟Grace计划去服装批发市场“消费”。 只不过&#xff0c;与以往普通进店客人身份不…

ArcGIS中将测绘数据投影坐标(平面坐标)转地理坐标(球面经纬度坐标)

目录 前言1.测绘数据预览1.1 确定带号1.2 为什么是对Y轴分带&#xff0c;而不是对X轴分带&#xff1f; 2 测绘数据转shp2.1 添加数据2.2 显示XY数据2.3 添加经纬度字段2.4 计算经纬度 3.shp数据重投影4.总结 前言 最近在刚好在做一个小功能&#xff0c;将测绘数据转为经纬度坐标…