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

news2024/11/20 7:24:58

简介

  • 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();            // 返回默认的整数值 0
        std::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.coloradmin.cn/o/1881810.html

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

相关文章

华为HCIP Datacom H12-821 卷19

1.多选题 如图所示,RTA 的 GE0/0/0、GE0/0/1 接口分别连接部门 1 和 2,其网段分别为 10.1.2.0/24、 10.1.3.0/24 网段,为限制部门 1 和 2 之间的相互访问,在 RTA 上部署 traffic-filter,以下哪些部署方式是正 确? A、配置 ACL3000 拒绝源为 10.1.2.0/24 目的为 10.1.3.0…

智谱AI ChatGLM-4使用教程:函数调用Function calling(赠送免费500w token)

文章目录 智谱AI介绍ChatGLM介绍token资源包函数调用能力编写函数参数列表的 `JSON` 描述函数调用选择Function Call 流程实践智谱AI介绍 北京智谱华章科技有限公司(简称“智谱AI”)致力于打造新一代认知智能大模型,专注于做大模型的中国创新。公司合作研发了中英双语千亿级…

剑神诀_单机架设_无需虚拟机_小白专用

前言 今天给大家带来一款单机游戏的架设&#xff1a;剑神诀&#xff0c;一键端 无需虚拟机 如今市面上的资源参差不齐&#xff0c;大部分的都不能运行&#xff0c;本人亲自测试&#xff0c;运行视频如下&#xff1a; 剑神诀 搭建教程 此游戏架设不需要安装虚拟机&#xff0c;…

大会员体系是如何让积分流动起来,实现跨业态引流的?

积分&#xff0c;是大会员体系建设的重点&#xff0c;也是难点之一。 假设积分跨业态或者跨品牌流通&#xff0c;但没有一套统一的积分结算体系&#xff0c;就容易出现各业态或品牌利益分配不均的问题。 因此&#xff0c;大会员体系能有效落地的重点之一&#xff1a;集团必须…

AI绘画Stable Diffusion 双重曝光-神秘意境和难以言喻的视觉体验,SD提示词轻松搞定

大家好&#xff0c;我是画画的小强 今天给大家介绍AIGC绘图提示语使用常见摄影手法&#xff1a;双重曝光。双重曝光摄影效果是一种摄影爱好所热衷的常见摄影手法之一。通过双重曝光摄影手法&#xff0c;能够为图同摄影图像引入神秘的意境感和一种难以言喻的视觉体验&#xff0…

python基础_类

在Python中&#xff0c;类&#xff08;Class&#xff09;是面向对象编程&#xff08;OOP&#xff09;的核心概念之一。类提供了一种创建新对象的模板&#xff0c;这些对象通常被称为类的实例或对象。以下是关于Python类的一些关键点和特性&#xff1a; 定义类 类通过class关键…

Swagger php注解常用语法梳理

Swagger php注解常用语法梳理 快速编写你的 RESTFUL API 接口文档工具&#xff0c;通过注释定义接口和模型&#xff0c;可以和代码文件放置一起&#xff0c;也可以单独文件存放。 Swagger 优势 通过代码注解定义文档&#xff0c;更容易保持代码文档的一致性模型复用&#xff0…

CSS 背景添加白色小圆点样式

css也是开发过程中不可忽视的技巧 此专栏用来纪录不常见优化页面样式的css代码 效果图: 未添加之前: 代码: background: radial-gradient(circle at 1px 1px, #3d3c3c 2px, transparent 0);background-size: 20px 25px;

Java代码生成器(开源版本)

一、在线地址 Java在线代码生成器&#xff1a;在线访问 二、页面截图 三、核心功能 支持Mybatis、MybatisPlus、Jpa代码生成使用 antlr4 解析SQL语句&#xff0c;保证了SQL解析的成功率支持自定义包名、作者名信息支持自定义方法名、接口地址支持自定义选择是否生成某个方法…

沃尔玛自养号测评:从入门到精通的全方位指南

沃尔玛测评自养号优势要点及IP环境搭建技术及主要可以归结为以下几个方面&#xff1a; 一、沃尔玛IP环境搭建技术 1.使用国外的服务器&#xff1a;为了确保测评活动的隐蔽性和安全性&#xff0c;卖家需要选择使用国外的服务器&#xff0c;并通过远程搭建一个安全终端防火墙。…

IDEA中Java源文件编译后class文件中文乱码

文章目录 一、设置 一、设置 路径&#xff1a;File -> Settings -> Bulid, Execution,Deployment -> Compiler -> Java Compiler

2024年度潍坊市职业技能大赛——网络搭建(网络与信息安全管理员)职业技能竞赛样题

2024年度潍坊市职业技能大赛 ——网络搭建&#xff08;网络与信息安全管理员&#xff09;职业技能竞赛样题 网络搭建职业技能竞赛组委会 2024年6月 一、项目简介 &#xff08;一&#xff09;竞赛须知 1.技能操作比赛时间150分钟&#xff0c;你需要合理分配时间。 2.如果没…

为什么越来越多的企业选择外包?赋能企业未来

软件开发过程包括设计需求、设计方案、产品研发、产品交付、后期维护&#xff0c;许多企业并沒有软件开发的专业能力与工作经验&#xff0c;将软件开发工作进行外包是比较节约成本的&#xff0c;企业能少走不少弯路。 YesPMP平台&#xff08;一站式软件外包、项目外包服务-YesP…

自适应站长跑路单页网站源码

跑路单页HTML源码自行修改文字就行了,上传到服务器里面运行即可&#xff0c;本地运行的话音乐会加载不出来&#xff0c;涉及到跨域问题 自适应站长跑路单页网站源码

ssm校园二手交易平台小程序

设计技术&#xff1a; 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringMybatisSpringMvc微信小程序 工具&#xff1a;IDEA、Maven、Navicat 主要功能&#xff1a; (a) 管理员&#xff1b;管理员进入系统主要功能包括首页&#xff0c;个人中心&…

ollama+Dify大模型本地化部署打造个人知识库 (2)

ollama大模型部署-CSDN博客文章浏览阅读26次。Ollama 是一个能在本地机器上轻松构建和运行大型语言模型的轻量级、可扩展框架&#xff0c;适用于多种场景&#xff0c;具有易于使用、资源占用少、可扩展性强等特点。https://blog.csdn.net/weixin_72819498/article/details/1400…

SAP ABAP 常用的参数

目录 一&#xff0c;创建一个单一的输入域&#xff1a;PARAMETERS 二&#xff0c;必输&#xff1a;OBLIGATORY 三&#xff0c;初始值&#xff1a;DEFAULT 四&#xff0c;按钮&#xff1a;复选框 checkbox 五&#xff0c;单选框 RADIOBUTTON GROUP 六&#xff0c;多值的选…

Oracle连接mysql

oracle使用的11g&#xff0c;在一台windows服务器&#xff1b;mysql使用的是5.7版本&#xff0c;在另一台windows服务器&#xff0c;这两个服务器之间的网络是互通的。做BI时&#xff0c;要获取不同数据源的数据&#xff0c;这些数据源可能是Oracle&#xff0c;也可能是sqlserv…

Veno File Manager(VFM)v4.2.7 中文包整理

Veno File Manager&#xff08;VFM&#xff09;是一个简单灵活的即插即用文件管理器&#xff0c;易于使用且具有许多选项。将文件发送给您的客户&#xff0c;使用专用文件夹创建新用户&#xff0c;或仅用作您的个人文件云。从任何设备访问&#xff0c;用户管理和从直观的管理面…

基于flask的闪现、g对象、蓝图

【 一 】闪现&#xff08;flash&#xff09; # 1 flask中得闪现存放数据的地方&#xff0c;一旦取了&#xff0c;数据就没了-实现跨请求间传递数据 # 2 django中有没有类似的东西&#xff1f;message 消息框架# 3 基本使用1 设置&#xff1a;flash(欢迎你、欢迎来到澳门赌场&a…