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.mzph.cn/pingmian/37956.shtml

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

相关文章

Java数据结构6-栈与队列

1. 栈(Stack) 1.1 概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则 压栈…

机电公司管理小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;管理员管理&#xff0c;客户管理&#xff0c;公告管理&#xff0c;考勤管理&#xff0c;请假管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;公告&#xff0c;机电零件&…

gitee配置ssh教程

生成公钥 执行命令&#xff1a; ssh-keygen -t rsa查看公钥 cat ~/.ssh/id_rsa.pub这个公钥就是要复制粘贴到Gitee中的ssh公钥。 配置Gitee SSH公钥 来到Gitee的ssh公钥中&#xff0c;配置

代码随想录算法训练营第四十六天| 121. 买卖股票的最佳时机 ,122.买卖股票的最佳时机II,123.买卖股票的最佳时机III

121. 买卖股票的最佳时机 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int maxProfit(int[] prices) {if(prices.length 0){return 0;}int[][] dp new int[prices.length][2];dp[0][0] 0;dp[0][1] -prices[0];for(int i1;i<prices.length;i){dp[i][0…

Go环境安装---附带每一步截图

Windows环境 Go安装包下载 下载后直接安装步骤按照即可。 测试 winR 输入cmd 在命令行输出go version可以看到自己的版本。 go env 查看环境变量 在桌面创建hello.go的文件 编写代码。注意&#xff0c;编码必修是UTF-8 在命令行输入路径刚刚代码所在的路径&#x…

动态选线,动态的选择变量的位宽

一、原理 参考博客&#xff1a;&#xff1c;Verilog&#xff1e; 语法技巧&#xff1a;数据位操作_verilog移位操作-CSDN博客 下图是从作者的博客cv过来的一张图&#xff0c;讲的非常的清晰。实现了动态的选择选择数据的位宽&#xff0c;只需要动态的改变base_expr就可以。 …

Python 潮流周刊#58:最快运行原型的语言

△△请给“Python猫”加星标 &#xff0c;以免错过文章推送 本周刊由 Python猫 出品&#xff0c;精心筛选国内外的 250 信息源&#xff0c;为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景&#xff1a;帮助所有读者精进 Python 技术&am…

暑假集中备考2024年汉字小达人:来做18道历年选择题备考吧

结合最近几年的活动安排&#xff0c;预计2024年第11届汉字小达人比赛还有4个多月就启动&#xff0c;那么孩子们如何利用这段时间有条不紊地准备汉字小达人比赛呢&#xff1f; 我的建议是充分利用即将到来的暑假&#xff1a;①把小学1-5年级的语文课本上的知识点熟悉&#xff0…

Python应用开发——30天学习Streamlit Python包进行APP的构建(12)

st.checkbox 显示复选框部件。 Function signature[source] st.checkbox(label, valueFalse, keyNone, helpNone, on_changeNone, argsNone, kwargsNone, *, disabledFalse, label_visibility"visible") Returns (bool) Whether or not the checkbox is checked. …

昇思25天学习打卡营第04天|数据集 Dataset

数据是深度学习的基础&#xff0c;高质量的数据输入将在整个深度神经网络中起到积极作用。MindSpore提供基于Pipeline的数据引擎&#xff0c;通过数据集&#xff08;Dataset&#xff09;和数据变换&#xff08;Transforms&#xff09;实现高效的数据预处理。其中Dataset是Pipel…

【QT】设置QTabWidget样式:上、下边线的显示与去除

目录 0.简介 1.环境 2.详细介绍 2.1我的原代码和显示效果 2.2 去掉QTabWidget的边框 2.3 单独留下边线 2.3.1 法一&#xff1a;通过【this->setDocumentMode(true);】设置下边线 2.3.2 通过【QTabWidget::pane】设置下边线 2.4单独设置上边线 2.5 优化界面tab 2.…

STM32的SPI通信

1 SPI协议简介 SPI&#xff08;Serial Peripheral Interface&#xff09;协议是由摩托罗拉公司提出的通信协议&#xff0c;即串行外围设备接口&#xff0c;是一种高速全双工的通信总线。它被广泛地使用在ADC、LCD等设备与MCU间&#xff0c;使用于对通信速率要求较高的场合。 …

css 布局出现无法去除的空白

案件介绍&#xff1a;在没有设置任何的css样式的情况下 文字顶部出现无法去除的空白 源代码 <div click"onClick" ><div class"tableTextButton--container"></div><Icon v-if"loading || thisLoading" type"ios-lo…

LeetCode热题100刷题2:283. 移动零、11. 盛最多水的容器、15. 三数之和、42. 接雨水

283. 移动零 挺简单的没啥说的 class Solution { public:void moveZeroes(vector<int>& nums) {//快慢指针 // 快指针负责往前遍历&#xff0c;慢指针记录快指针遍历过的把0撵走的最后一个元素的位置// 然后快指针遍历完之后&#xff0c;慢指针到结尾直接赋0就行in…

LeetCode题练习与总结:环形链表Ⅱ--142

一、题目描述 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测…

数据资产驱动的智能化转型之路:深入解析数据资产在数字化转型中的核心作用,构建全面、智能的数据资产解决方案,助力企业实现智能化运营和决策,引领行业创新

目录 一、引言 二、数据资产在数字化转型中的核心作用 1、决策支持 2、业务优化 3、创新驱动 4、风险管理 三、构建全面、智能的数据资产解决方案 1、数据资产战略规划 2、数据资产采集与整合 3、数据资产治理 4、数据资产分析与挖掘 5、数据资产应用与服务 四、数…

【JVM-01】引言

【JVM-01】引言 1. 什么是JVM&#xff1f;2. JDK、JRE、JVM比较3.常用的JVM有那些4.学习路线 1. 什么是JVM&#xff1f; JVM即 Java Virtual Machine(Java虚拟机)&#xff0c;是Java程序运行的环境(Java 二进制字节码运行环境)。 好处&#xff1a; 一次编写&#xff0c;到处…

【操作系统期末速成】EP05 | 学习笔记(基于五道口一只鸭)

文章目录 一、前言&#x1f680;&#x1f680;&#x1f680;二、正文&#xff1a;☀️☀️☀️2.1 考点十一&#xff1a;死锁的概念与预防2.2 考点十二&#xff1a;死锁的避免一银行间算法2.1 考点十三&#xff1a;死锁的检测与解除 一、前言&#x1f680;&#x1f680;&#x…

【wsl2】升级wsl及ubuntu22.04

y9kp的wsl2 还是用的自己的子网 很久没用wsl2的ubutnu22.04系统 发现无法启动 等待了挺久&#xff0c;启动了 但同时我也在升级wsl中&#xff1a; 升级wsl wsl --update 这个升级是对ubuntu22.04的运行没影响。 apt-get update 然后upgrade wsl2的升级一直在90%多不动 然…

C语言 | Leetcode C语言题解之第206题反转链表

题目&#xff1a; 题解&#xff1a; struct ListNode* reverseList(struct ListNode* head) {if (head NULL || head->next NULL) {return head;}struct ListNode* newHead reverseList(head->next);head->next->next head;head->next NULL;return newHea…