toml11读,写,格式转换

前言

  1. 写这个文章的目的,还是因为在网上没有找到合适的资料,所以自己来写一个
  2. toml11简中的资料是在是太少.你去搜吧,能看的资料几乎没有.这也是我写这个文章的缘由.说白了还是用的人太少了.
  3. 官方的文档也是"过于简洁".只有github上的一个readme可以参考.资料太少就会导致你的开发周期被加长,时间被浪费.
  4. 你要是读文件还行, 也比较简单,但是一旦牵扯到格式转化,这个库也做不到,和我之前用的boost解析json确实有一些差距,所以我简单实现了一下.
  5. 比如toml中的布尔量,你定义一个a,a=false,这么写是可以;但是你,a=0;这种情况下,toml11却无法解析.这种情况下你给同事使用,无疑是增加了学习成本.
  6. 另外就是写数据到toml中,这个在toml11的文档中资料很少,简中一点都没搜到.我的文档中会对这个也有介绍.
  7. 针对上面所说的问题,这也是写这个文档的缘由.

官方资料

具体的还是看这个,怎么说这个是官方的资料

ToruNiina/toml11: TOML for Modern C++ (github.com)

读文件

toml::get_or

  toml::get_or 函数用于从 toml::value 对象中获取指定键的值。 如果键存在,则返回相应的值; 如果键不存在,则返回用户提供的默认值。

toml::get_or<double>(data, "a", 0.1) 
表示获取键为 "a" 的值,如果存在则返回对应的浮点数值,如果不存在则返回默认值 0.1。

需要注意的是,使用 toml::get_or 的前提是你能够确定配置项的类型,并且在键不存在时能够提供一个合适的默认值。

如果你无法确定类型或者默认值是无法确定的,可以使用其他处理方式,比如手动检查键是否存在 ,然后根据情况再使用 toml::find 或 toml::find_or。

toml::find_or

在 toml11 库中,toml::find_or 函数用于从 toml::value 对象中获取指定键的值。

toml::find_or<double>(data, "a", 0.1)
 表示获取键为 "a" 的值,如果存在则返回对应的浮点数值,如果不存在则返回默认值 0.1。

要注意的是:

toml文件中a=1.0,为浮点数。这么读肯定是没有问题的,toml::find_or<double>(data, "a", 0.1)

如果配置项不存在,就是默认值0.1如果配置项不是浮点数,他也是默认值。!!!这个要注意下

type

返回读取toml配置项的类型

auto valueType = toml::find(data, key).type();

find

在 toml11 中,toml::find 函数用于从 toml::value 对象中获取指定键的值。

template<typename T>
T find(const toml::value& v, const std::string& key);
不能指定默认参数

[fruit]
name = "apple"
[fruit.physical]
color = "red"
shape = "round"


const auto  data  = toml::parse("fruit.toml");
//当读取的不是具体条目的时候,不用指定类型
const auto& fruit = toml::find(data, "fruit");
//当读取的是具体条目的时候,需要指定类型——如果类型和toml中的类型不对的话,就会造成程序退出。内部是不会进行类型转换
const auto  name  = toml::find<std::string>(fruit, "name");

demo1

#include <toml.hpp>
#include <iostream>
#include <fstream>

int main() {
	// 创建一个 TOML 表
	toml::value data{
		{"title", "example"},
		{"owner", toml::value{
			{"name", "Tom Preston-Werner"},
			{"dob", "1979-05-27"}
		}},
		{"database", toml::value{
			{"server", "192.168.1.1"},
			{"ports", toml::array{8001, 8001, 8002}},
			{"connection_max", 5000},
			{"enabled", true}
		}}
	};

	// 将 TOML 表写入文件
	std::ofstream ofs("example.toml");
	ofs << data;

	// 检查写入是否成功
	if (ofs.good()) {
		std::cout << "Data successfully written to example.toml" << std::endl;
	}
	else {
		std::cerr << "Error writing to example.toml" << std::endl;
	}

	return 0;
}

结果

title = "example"

[owner]
name = "Tom Preston-Werner"
dob = "1979-05-27"

[database]
server = "192.168.1.1"
ports = [
8001,
8001,
8002,
]
connection_max = 5000
enabled = true

demo2

void writeToml()
{
	// 创建一个 TOML 文档
	toml::value doc;

	// 添加一些键值对、数组和表
	doc["key1"] = 42;           // 整数
	doc["key2"] = 3.14;         // 浮点数
	doc["key3"] = "hello";      // 字符串

	toml::array arr;
	arr.push_back(1);
	arr.push_back(2);
	doc["my_array"] = arr;      // 数组

	toml::value nested_table;
	nested_table["nested_key"] = "world";
	doc["nested"] = nested_table; // 表

	// 将文档输出为 TOML 字符串
	std::string toml_str = toml::format(doc);

	// 将 TOML 字符串写入文件
	std::ofstream file("./example.toml");
	file << toml_str;
	file.close();

	return;
}

结果

key1 = 42
key2 = 3.1400000000000001
key3 = "hello"
my_array = [1,2]
nested = {nested_key="world"}

多层嵌套

这个真是麻烦,而且也找不到资料,官方文档里也没怎么写。

我当时写的时候也是非常费劲,我这边是双层map遍历,牵扯到读,写,修改,以及判断某些配置项是否存在,并且和map同步确实有点复杂。

我就两个建议,如果你不是非toml必选,我建议你换。toml是很好,toml11我觉得还是差点。

另外就是问AI,但根据我的经验来看,你问大概率也是不对的,需要花一段改。这本质上还是因为toml11的资料少,投喂AI训练也不够。

格式转化

编译器最低支持C++17,才能编译.

支持默认值.支持类型转换,

使用方法:

配置文件

a="1"
b=0;
#c未在配置文件中

demo

//data:toml的toml::value key:toml的中配置项 default_value:该配置项的默认值
GetTomlValue(const toml::value &data, const std::string &key, const T &default_value)

int a= GetTomlValue<int>(data, "a", 200);//a在toml中是字符,这里转换成int类型读出来
bool b = GetTomlValue<bool>(data, "b", false);//b在toml中是是整形,这里转换成bool类型读出来
float c = GetTomlValue<bool>(data, "c",1.1);//c在toml中不存在,这里给c赋值默认值1.1

源码:

template <typename T>
T GetTomlValue(const toml::value &data, const std::string &key)
{
	if (!(is_same_v<T, string> || is_same_v<T, int> || is_same_v<T, unsigned int> || is_same_v<T, unsigned long long> || is_same_v<T, float> || is_same_v<T, bool>))
	{
		LogError("Toml文件函数模板,目前只处理了string,int,unsigned int,unsigned long long,float,bool这四个常用类型。其他类型手动添加下即可");
		exit(-1);
	}
	auto valueType = toml::find(data, key).type();
	switch (valueType)
	{
	case toml::value_t::integer:
	{
		unsigned long long value = toml::find<unsigned long long>(data, key);
		if constexpr (is_same_v<std::decay_t<T>, int> || is_same_v<T, unsigned int> || is_same_v<T, unsigned long long> || is_same_v<T, float> || is_same_v<T, bool>)
			return value;
		else {
			LogError(key + "TOML文件类型转化,不支持从int转化到" + (string) typeid(T).name());
			exit(-1);
		}
	}
	break;
	case toml::value_t::floating:
	{
		float value = toml::find<float>(data, key);
		if constexpr (std::is_same_v<std::decay_t<T>, float>) // 想要的是float
			return value;
		else if constexpr (std::is_same_v<std::decay_t<T>, int>) // 想要的是int
			return static_cast<int>(value);
		else {
			LogError(key + "TOML文件类型转化,不支持从float转化到" + (string) typeid(T).name());
			exit(-1);
		}
	}
	break;
	case toml::value_t::string:
	{
		string value = toml::find<string>(data, key);
		if constexpr (std::is_same_v<std::decay_t<T>, string>) // 想要的是string
			return value;
		else if constexpr (std::is_same_v<std::decay_t<T>, int>)
			return stoi(value);
		else if constexpr (std::is_same_v<std::decay_t<T>, unsigned int>)
			return stoul(value);
		else if constexpr (std::is_same_v<std::decay_t<T>, unsigned long long>)
			return stoull(value);
		else if constexpr (std::is_same_v<std::decay_t<T>, float>)
			return stof(value.c_str());
		else if constexpr (std::is_same_v<std::decay_t<T>, bool>)
		{
			if (value == "1" || value == "0")
				return atoi(value.c_str());
			else if (value == "true")
				return 1;
			else if (value == "false")
				return 0;
			else
			{
				LogError("Toml文件配置项,布尔量" + key + "=" + value + ",应该在0,1或true,false选择");
				exit(-1);
			}
		}
		else {
			LogError(key + "TOML文件类型转化,不支持从string转化到" + (string) typeid(T).name());
			exit(-1);
		}
		break;
	}
	case toml::value_t::boolean:
	{
		if constexpr (std::is_same_v<std::decay_t<T>, bool>)
			return toml::find<bool>(data, key);
		else {
			LogError(key + "TOML文件类型转化,不支持从bool转化到" + (string) typeid(T).name());
			exit(-1);
		}
	}
	break;
	// 其他类型的处理
	default:
		LogError("TOML文件类型转化,我做的GetTomlValue函数模板,不支持这个类型,可以尝试练习我做个适配!");
		exit(-1);
		break;
	}
	return 0;
}

template <typename T>
T GetTomlValue(const toml::value &data, const std::string &key, const T &default_value)
{
	return data.contains(key) ? GetTomlValue<T>(data, key) : default_value;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mysql中varchar与bigint直接比较会导致精度丢失以至于匹配到多行数据

在mysql中&#xff0c;我们都知道如果一个索引字段使用了函数或者计算那么查询的时候索引会失效&#xff0c;可是我相信在联表的时候我们只会关注两个表关联字段是否都创建了索引&#xff0c;却没有关注过这两个字段的类型是否一致&#xff0c;如果不一致的话索引是会失效的&am…

Redis 实战3

系列文章目录 本文将从跳跃表的实现、整数集合来展开 Redis 实战 Ⅲ 系列文章目录跳跃表的实现跳跃表节点层 前进指针跨度 整数集合的实现升级升级的好处提升灵活性节约内存 降级整数集合 API总结 跳跃表的实现 Redis 的跳跃表由 redis.h/zskiplistNode 和 redis.h/zskiplist…

面向初学者:什么是图数据库

当数据成为关键生产要素&#xff0c;许多企业开始面临利用海量数据辅助企业复杂决策的现实难题。而在数据爆发式增长&#xff0c;关联复杂度激增的趋势下&#xff0c;图数据库成为企业加工关联数据、挖掘隐藏价值、智能决策升级的关键技术之一&#xff0c;在全球范围内开始被使…

如何更快地执行 Selenium 测试用例?

前言&#xff1a; 当我们谈论自动化时&#xff0c;首先想到的工具之一是 Selenium。我们都知道Selenium WebDriver 是一个出色的 Web 自动化工具。实施Selenium 自动化测试的主要原因是加速 selenium 测试。在大多数情况下&#xff0c;Selenium 的性能比手动的要好得多。但是&…

(2024,DONN,OCNN,复数域,交替的非线性激活层与振荡器层,复值反向传播)深度振荡神经网络

Deep Oscillatory Neural Network 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 1. 简介 2. 方法 2.1 深度振荡神经网络&#xff08;DONN&#xff09; 2.2 振荡卷积神经网…

人物特效游戏玩法,门坎低,适合新手上手项目【揭密】

项目简介&#xff1a; 本项目涉及我们日常使用的美肤产品和效果维持&#xff0c;我们需要提交自己的作品&#xff0c;完成官方网站发布的任务。任务完成后&#xff0c;提交审核&#xff0c;一旦审批通过&#xff0c;收益就会到账。 项 目 地 址 &#xff1a; laoa1.cn/1961.…

Python-VBA函数之旅-round函数

目录 一、round函数的常见应用场景 二、round函数使用注意事项 三、如何用好round函数&#xff1f; 1、round函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、推荐阅读&#xff1a; 个人主页&#xff1a; https://blog.csdn.net/ygb_1024?spm1010.2…

部署tomcat部署LNAMT

这里写目录标题 部署tomcatjava环境安装 部署LNAMT更改tomcat端口号 tomcat就是中间件之一&#xff0c;tomcat本身是一个容器&#xff0c;专门用来运行java程序&#xff0c;java语言开发的网页.jsp就应该运行于tomcat中。而tomcat本身的运行也依赖于jdk环境。 部署tomcat java…

LVS 负载均衡部署 NAT模式

一、环境准备 配置环境&#xff1a; 负载调度器&#xff1a;配置双网卡 内网&#xff1a;172.168.1.11(ens33) 外网卡&#xff1a;12.0.0.1(ens37)二台WEB服务器集群池&#xff1a;172.168.1.12、172.168.1.13 一台NFS共享服务器&#xff1a;172.168.1.14客户端&#xff…

2024年全网最新AI实景自动无人直播软件:引领智能直播新潮流;打造智能化、互动性强的直播平台

随着互联网的飞速发展&#xff0c;直播已经成为商家品牌推广和产品宣传的重要方式。然而&#xff0c;AI实景自动无人直播软件的问世&#xff0c;进一步推动了直播行业的智能化进程&#xff0c;为商家带来了全新的直播体验。&#xff08;ai无人自动直播大量招商加盟&#xff1b;…

【解疑】ZIP分卷压缩文件如何设置和取消密码?

压缩大文件&#xff0c;我们可以设置压缩成ZIP分卷文件&#xff0c;这样更利于传输和存储。如果分卷文件比较重要&#xff0c;还可以设置密码保护&#xff0c;那ZIP分卷压缩文件的密码如何设置和取消呢&#xff1f;下面一起来看看吧&#xff01; 设置ZIP分卷密码&#xff1a; …

配电室智能巡检机器人

近年来&#xff0c;生产过程高度自动化&#xff0c;各工矿企业关键场所需定期巡检维护。但目前巡检主要靠人工&#xff0c;既耗时费力效率又低&#xff0c;且受环境等因素影响&#xff0c;巡检难以全面规范&#xff0c;隐患或问题易被忽视。在此情况下&#xff0c;如何利用现有…

Python爬虫基础知识学习(以爬取某二手房数据、某博数据与某红薯(书)评论数据为例)

一、爬虫基础流程 爬虫的过程模块化&#xff0c;基本上可以归纳为以下几个步骤&#xff1a; 1、分析网页URL&#xff1a;打开你想要爬取数据的网站&#xff0c;然后寻找真实的页面数据URL地址&#xff1b; 2、请求网页数据&#xff1a;模拟请求网页数据&#xff0c;这里我们介…

安卓模拟器访问主机局域网

误打误撞能够访问主机局域网了 但是不太懂是因为哪一部分成功的 先记录一下 PC&#xff1a;mac系统 安卓编译器&#xff1a;Android Studio 步骤 只需要在PC上进行设置 1. 在【设置】中&#xff0c;打开已连接的Wi-Fi的【详细信息】 2. TCP/IP --> 配置IPv6&#xff0c;修…

roofline model加速模型部署最后一公里

文章目录 模型部署教程来啦:)什么是Roofline Model&#xff1f;算法模型相关指标计算量计算峰值参数量访存量带宽计算密度kernel size对计算密度的影响output size对计算密度的影响channel size对计算密度的影响group convolution对计算密度的影响tensor reshape对计算密度的影…

网站使用SSL证书有什么好处

SSL证书是一种用于加密在网络上传输的数据以确保安全性和隐私的数字证书。下面我们来谈谈一个网站使用SSL证书后有哪些好处&#xff1a; 首先&#xff0c;使用SSL证书可以保护用户的隐私。在没有SSL证书的情况下&#xff0c;用户的个人信息和敏感数据可能会被黑客窃取或篡改。…

npm安装指定版本,npm删除依赖,卸载依赖

安装指定版本 npm中安装指定的版本号&#xff0c;格式为 ‘包名版本号’ npm install 包名称版本号 --save 例如安装jquery: npm install jquery3.0.0 --save在package.json里面可以看到对应的包&#xff1a; "jquery": "^3.0.0"注意&#xff1a;已有…

基于springboot实现医院药品管理系统项目【项目源码+论文说明】

基于springboot实现医院药品管理系统演示 摘要 身处网络时代&#xff0c;随着网络系统体系发展的不断成熟和完善&#xff0c;人们的生活也随之发生了很大的变化&#xff0c;人们在追求较高物质生活的同时&#xff0c;也在想着如何使自身的精神内涵得到提升&#xff0c;而读书就…

CentOS 重启网络失败service network restart

命令 service network restart 提示 Job for network.service failed because the control process exited with error code. See “systemctl status network.service” and “journalctl -xe” for details. 原因分析 使用journalctl -xe命令查看日志后的具体错误 -- Un…

基于springboot实现疾病防控综合系统项目【项目源码+论文说明】

基于springboot实现疾病防控综合系统演示 摘要 在如今社会上&#xff0c;关于信息上面的处理&#xff0c;没有任何一个企业或者个人会忽视&#xff0c;如何让信息急速传递&#xff0c;并且归档储存查询&#xff0c;采用之前的纸张记录模式已经不符合当前使用要求了。所以&…
最新文章