使用C对TOML文件的解析

2023-10-31


TOML是前GitHub CEO, Tom Preston-Werner,于2013年创建的语言,其目标是成为一个小规模的易于使用的语义化配置文件格式。TOML被设计为可以无二义性的转换为一个哈希表(Hash table)。

toml书写语法

参考这里

解析toml文件

这里使用tomlc99

#下载库
git clone https://github.com/cktan/tomlc99.git
cd tomlc99
#创建test.c文件
vi test.c

将以下代码复制到test.c文件中

#ifdef NDEBUG
#undef NDEBUG
#endif

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdint.h>
#include <assert.h>
#include "toml.h"

typedef struct node_t node_t;
struct node_t {
    const char*   key;
    toml_table_t* tab;
};

node_t stack[20];
int stacktop = 0;

/*设置输出颜色*/
#define red_color "\E[1;31m"
#define color_suffix "\E[0m"

static void print_array_of_tables(toml_array_t* arr, const char* key);
static void print_array(toml_array_t* arr);

/**
 * @brief 打印表名
 * 
 * @param arrname 数组名或者是表名
 */
static void print_table_title(const char* arrname)
{
    int i;
    printf("%s", arrname ? "[[" : "[");
	/*打印上级*/
    printf(red_color"开始打印上级:"color_suffix);
    for (i = 1; i < stacktop; i++) {
	printf("%s", stack[i].key);
	if (i + 1 < stacktop)
	    printf(".");
    }
	/*打印尾部*/
	printf(red_color"打印尾部:"color_suffix);
    if (arrname)
	printf(".%s]]\n", arrname);
    else
	printf("]\n");
}

/**
 * @brief 打印表
 * 
 * @param curtab 
 */
static void print_table(toml_table_t* curtab)
{
    int i;
    const char* key;
    const char* raw;
    toml_array_t* arr;
    toml_table_t* tab;

	/*轮询KEY*/
    for (i = 0; 0 != (key = toml_key_in(curtab, i)); i++) {
		/*如果是KV则打印*/
	if (0 != (raw = toml_raw_in(curtab, key))) {
		printf(red_color"如果是KV则打印\n"color_suffix);
	    printf("%s = %s\n", key, raw);
		/*如果是表中数组或者KV型数组*/
	} else if (0 != (arr = toml_array_in(curtab, key))) {
		/*[[key]]数组或者KV型数组*/
	    if (toml_array_kind(arr) == 't') {
	    	printf(red_color"如果是[[key]]数组\n"color_suffix);
		print_array_of_tables(arr, key);
	    }
	    else {
			/*KV型数组*/
			printf(red_color"如果是KV型数组\n"color_suffix);
		printf("%s = [\n", key);/*xx = [ss,sss]*/
		print_array(arr);
		printf("    ]\n");
	    }
	} else if (0 != (tab = toml_table_in(curtab, key))) {
		/*如果是[tab.tab]嵌套则分解*/
		printf(red_color"如果是[tab.tab]嵌套则分解打印\n"color_suffix);
	    stack[stacktop].key = key;
	    stack[stacktop].tab = tab;
	    stacktop++;
	    print_table_title(0);
	    print_table(tab);
	    stacktop--;
	} else {
	    abort();
	}
    }
}

/**
 * @brief 打印标表中数组
 * 
 * @param arr 数组指针
 * @param key 数组名
 */
static void print_array_of_tables(toml_array_t* arr, const char* key)
{
    int i;
    toml_table_t* tab;
    printf("\n");
	/*轮询表中数组*/
	printf(red_color"轮询表中数组\n"color_suffix);
    for (i = 0; 0 != (tab = toml_table_at(arr, i)); i++) {
	print_table_title(key);//[[key]]
	print_table(tab);
	printf("\n");
    }
}

/**
 * @brief 打印数组
 * 
 * @param curarr 
 */
static void print_array(toml_array_t* curarr)
{
    toml_array_t* arr;
    const char* raw;
    toml_table_t* tab;
    int i;

    switch (toml_array_kind(curarr)) {
/*
[
	0: yyy,
	1: xxx,
	2: xxx,
]
*/
    case 'v': 
	for (i = 0; 0 != (raw = toml_raw_at(curarr, i)); i++) {
	    printf("  %d: %s,\n", i, raw);
	}
	break;
/*
[
	0:
		0:
			0:xxx
			1:xxx
		1:
			0:xxx
			1:xxx
	1:
		0:
			0:xxx
			1:xxx
		1:
			0:xxx
			1:xxx	
]
*/
    case 'a': 
	for (i = 0; 0 != (arr = toml_array_at(curarr, i)); i++) {
	    printf("  %d: \n", i);
	    print_array(arr);
	}
	break;
	    
    case 't': 
	for (i = 0; 0 != (tab = toml_table_at(curarr, i)); i++) {
	    print_table(tab);
	}
	printf("\n");
	break;
	
    case '\0':
	break;

    default:
	abort();
    }
}

/**
 * @brief 解析打印toml文件
 * 
 * @param fp 
 */
static void cat(FILE* fp)
{
    char  errbuf[200];
    
    toml_table_t* tab = toml_parse_file(fp, errbuf, sizeof(errbuf));
    if (!tab) {
	fprintf(stderr, "ERROR: %s\n", errbuf);
	return;
    }

    stack[stacktop].tab = tab;
    stack[stacktop].key = "";
    stacktop++;
    print_table(tab);
    stacktop--;

    toml_free(tab);
}

int main(int argc, const char* argv[])
{
    int i;
    if (argc == 1) {
	cat(stdin);
    } else {
	for (i = 1; i < argc; i++) {
	    
	    FILE* fp = fopen(argv[i], "r");
	    if (!fp) {
		fprintf(stderr, "ERROR: cannot open %s: %s\n",
			argv[i], strerror(errno));
		exit(1);
	    }
	    cat(fp);
	    fclose(fp);
	}
    }
    return 0;
}

准备测试的toml文件,写入到同级目录的sample.toml文件中

[Service]
  Port = 50000
  Timeout = 5000
  ConnectRetries = 10
  Labels = [ 'MQTT_Protocol' ,'MODBUS_Protocol' ]
  StartupMsg = 'mqtt modbus device service started'
  CheckInterval = '10s'

[Clients]
  [Clients.Data]
    Host = 'localhost'
    Port = 48080

  [Clients.Metadata]
    Host = 'localhost'
    Port = 48081

[Device]
  DataTransform = false
  Discovery = false
  MaxCmdOps = 128
  MaxCmdResultLen = 256

[Logging]
  LogLevel = 'DEBUG'

[[DeviceList]]
  Name = 'modbus-01_hangzhou-temperature_device-1'
  Profile = 'modbus_temperature_device_profile_common'
  Description = 'An temperature device'
  [DeviceList.Protocols]
    [DeviceList.Protocols.modbus-rtu]
      Address = '/tmp/slave'
      BaudRate = 9600
      DataBits = 8
      StopBits = 1
      Parity = 'N'
      UnitID = 1
  [[DeviceList.AutoEvents]]
    Resource = 'temperature'
    OnChange = false
    Frequency = '10s'
  [[DeviceList.AutoEvents]]
    Resource = 'humidity'
    OnChange = true
    Frequency = '15000ms'

[[DeviceList]]
  Name = 'modbus-01_hangzhou-temperature_device-2'
  Profile = 'modbus_temperature_device_profile_common'
  Description = 'An temperature device'
  [DeviceList.Protocols]
    [DeviceList.Protocols.modbus-rtu]
      Address = '/tmp/slave'
      BaudRate = 9600
      DataBits = 8
      StopBits = 1
      Parity = 'N'
      UnitID = 2
  [[DeviceList.AutoEvents]]
    Resource = 'temperature'
    OnChange = false
    Frequency = '10s'
  [[DeviceList.AutoEvents]]
    Resource = 'humidity'
    OnChange = true
    Frequency = '15000ms'
gcc toml.c test.c -o test
#增加执行权限
sudo chmod +x test
#运行解析
./test sample.toml

测试输出内容如下

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用C对TOML文件的解析 的相关文章

  • 边缘计算

    多接入边缘计算 xff08 MEC xff09 是云计算之后的又一项突破性技术 xff0c 该技术有望使得应用和内容更接近网络边缘 xff0c 能够降低网络延迟 xff0c 并提供新的服务 iGR Research的分析师Iain Gill
  • 基于人工智能与边缘计算Aidlux的工业表面缺陷检测

    一 训练yolov8得到onnx模型 相关教程有很多 二 模型转化 网站 https aimo aidlux com 输入试用账号和密码 账号 AIMOTC001 密码 AIMOTC001 我们选择 TensorFlowLite 一步步完成
  • 边缘计算2.0时代,“云边缘”与“边缘云”你分清了吗?

    5G时代的来临 意味着整个世界的连接 计算 和沟通方式都将迎来巨大的改变 这样的改变挑战着每一个人对于未来的想象力 越来越多的 低时延 大带宽 业务需求将会涌现 与此同时 大规模的数据激增也给整个行业和企业带来了不小的挑战 2020年对于全
  • 区块链如何应用于边缘计算、隐私计算联邦学习

    近年来数据安全事件频发 数据安全威胁日益严峻 随着 中华人民共和国数据安全法 的颁布和实施 对企业合规安全地发挥数据价值提出了更高的要求 如何在保障数据安全的前提下发挥数据价值 平衡效率和风险 是当前面临的重要课题 本文探讨如何将区块链应用
  • spark机器学习训练模型示例(一)

    利用逻辑回归建立模型 建立训练集和测试集 from pyspark ml import Pipeline from pyspark ml classification import LogisticRegression from pyspa
  • 【模型压缩】网络层与算子融合

    由于深度学习网络层数深 结构复杂 生成的算子数量众多 带了巨大的计算资源在和时间的消耗 业界对于加速算子的计算展开了一定研究 比较经典的方法是将多个算子重新组合成一个新的算子 同时对生成的代码进行底层的性能优化 融合成新算子后计算相对于多个
  • IOTCS+Ekuiper搭建物联网边缘计算平台

    背景介绍 IOTCS 是专为物联网平台而设计的工业智能网关 自从 2020 年 10 月以来 我们从需求调研 设计 定型 研发 测试经过漫长的沉淀与孵化 最终顺利实现工业智能网关最初的设想 我们凭借创新设计理念 快捷的安装以及部署 易用的扩
  • NVIDIA TX2上ROS安装

    TX2上的ROS自动安装git上有现成的 记录如下 首先 下载git上的自动安装脚本 gt git clone https github com jetsonhacks installROSTX2 git 其次 安装全量ros版本 inst
  • #3文献学习总结--边缘计算资源分配与任务调度优化

    文献 边缘计算资源分配与任务调度优化综述 1 系统模型 云 边 端 第 1 层是物联网层 传感器 处理器根据应用需求感知 测量和收集原始数据 在本地处理大量数据或将其上传至计算节点 第 2 层是边缘计算层 位于互联网边缘 靠近数据源 边缘计
  • 边缘计算初探:什么是边缘计算,它能做什么?

    边缘计算是指在靠近智能设备或数据源头的一端 提供网络 存储 计算 应用等能力 达到更快的网络服务响应 更安全的本地数据传输 边缘计算可以满足系统在实时业务 智能应用 安全隐私保护等方面的要求 为用户提供本地的智能服务 边缘计算一般由云端管理
  • Day20【元宇宙的实践构想06】—— 元宇宙与Web3.0

    本人简介 男 年龄 18 作者 那就叫我亮亮叭 专栏 元宇宙 部分资料参考文献 成生辉教授的 元宇宙 概念 技术及生态 和百度相关资料 0 0 写在前面 元宇宙 在2021年成为时髦的概念 元宇宙到底是什么 元宇宙是否是互联网技术的下一次革
  • RK3588移植-opencv交叉编译aarch64

    文章目录 概括 准备资源 编译Opencv 修改CMakelist文件 将lib库复制到 lib目录 问题 opencv videoCapture无法运行视频 安装历程 history 注意 本文中的所有配置相关路径都与当前安装的路径有关
  • 工业协议网关IOTCS企业版正式发布

    一 发布前言 继今年5月份IOTCS开源版本发布以后 我们依然在致力于开源版的功能升级迭代 目前南向驱动类型支持OPCUA与Siemens S7协议 1200 1500型号 以及Modbus全协议 北向资源有HTTP MQTT 通过不同的连
  • 什么是边缘计算网关?

    边缘计算网关 简称 边缘网关 将云端功能扩展到本地的边缘设备 使边缘设备能够快速自主地响应本地事件 提供低延时 低成本 隐私安全 本地自治的本地计算服务 同时所有服务都以 Docker 镜像方式安装 真正做到了跨平台 部署快捷 易管理 在链
  • IOTCS解决Actor异常报告、驱动优化

    近日 我们发布了 IOTCS0 8 版本 版本主要解决了Actor异常报告 解决消息处理问题 此外 新增南向驱动BACNet 修复了PLC驱动连接参数 实时监测驱动连接状态 统一的数据格式处理 与此同时我们对现有版本其它模块进行了功能优化
  • KubeEdge环境搭建(支持网络插件flannel)

    KubeEdge环境搭建 准备工作 K8s集群环境搭建 准备开始 配置国内镜像 仅amd64架构 如果是arm架构的不要更改镜像 安装docker 安装K8s 初始化Master节点 网络插件安装 部署可视化KuBoard Cloud节点配
  • 大数据时代移动边缘计算架构中的差分隐私保护(二)

    大数据时代移动边缘计算架构中的差分隐私保护 二 实际上 给数据加拉普拉斯噪声或者是指数噪声是针对中心式的差分隐私处理框架的 对于本地化的差分隐私处理框架 现在已有的是采用随即相应技术 Bloom Filter等技术满足 本地化差分隐私 LD
  • 人工智能边缘计算:连接智能的边界

    导言 人工智能边缘计算是将智能计算推向数据源头的重要发展方向 本文将深入探讨边缘计算与人工智能的交融 以及在未来数字化社会中的前景 1 边缘计算的基础 分布式计算 边缘计算通过将计算任务推送至数据产生的地方 实现更高效的分布式计算 低延迟通
  • 使用 serde 反序列化带有 Enum 键的 HashMap

    我有以下 Rust 代码 它模拟了一个配置文件 其中包括HashMap键控有一个enum use std collections HashMap use serde Deserialize Serialize derive Debug Cl
  • 无法安装kivy。为 kivy 构建轮子失败 (pyproject.toml)

    我不知何故搞砸了我的 pip 或我的 kivy 文件 我的也安装不了我试过了pip install kivy并且git clone https github com kivymd KivyMD git depth 1 我使用的是 macos

随机推荐

  • 串口通信(PC-51单片机)

    实验现象 下载程序后打开串口调试助手 将波特率设置为4800 选择发送的数据就可以显示 接线说明 具体接线图可见开发攻略对应实验的 实验现象 章节 注意事项 include reg52 h
  • Luci的工作流程

    1 浏览器敲入192 168 1 1后就 路由器作为uhttp server会把 www index html这个页面返回给浏览器 而且这个页面又会刷新 去请求页面 luci cgi 代码如红色标记
  • vue中使用cookies和crypto-js实现记住密码和加密

    不多BB 搞快 搞快 使用crypto js加解密 第一步 安装 npm install crypto js 第二步 在你需要的vue组件内import import CryptoJS from crypto js 第三步 使用 Encry
  • 【Idea技巧】01.Idea无法打开,报错 Start Failed

    序章 个人使用Idea版本 借鉴文章 添加链接描述 解决方案 管理员命令cmd netsh int ipv4 set dynamicport tcp start 49152 num 16383 netsh int ipv4 set dyna
  • 怎么用计算机计算年月份,如何使用Excel计算两个日期之间的月数?

    一 这可以通过DATEDIF函数完成 二 DATEDIF函数的定义 DATEDIF函数是Excel中的隐藏函数 而不是帮助和插入公式中的隐藏函数 返回两个日期之间的年 月 日间隔的数量 DATEDIF函数通常用于计算两个日期之间的时差 语法
  • Windows11之QT开发框架超详细下载安装与使用教程

    文章目录 前言 3 1 QT开发框架下载 3 2 QT开发框架安装 3 3 QT开发框架使用 总结 前言 本博客的主要内容为在Windows11系统下的QT开发框架的下载安装与使用教程 QT开发框架开发C 图形化界面十分有用 读者跟着我一步
  • 球坐标系下梯度、散度、旋度和拉普拉斯的简单计算

    转载于 https www cnblogs com hiramlee0534 p 5480045 html
  • 七天玩转Redis

    一 简要了解 redis是一个key value存储系统 和Memcached类似 它支持存储的value类型相对更多 包括string 字符串 list 链表 set 集合 zset sorted set 有序集合 和hash 哈希类型
  • ELK系列(九)、配置ES和Kibana的用户密码

    前面介绍的都是没有设置密码的情况 ES默认没有密码 什么数据泄露的新闻简直是家常便饭 所以这里还是建议大家给ES和kibana设置用户登陆 或者使用nginx限制IP或用户访问 本文介绍ELK自带的创建用户的方式 ELK系列 一 安装Ela
  • CSDN编程竞赛第六期

    CSDN编程竞赛报名地址 https edu csdn net contest detail 16 本次是我第二次参加CSDN举办的编程竞赛 这一次的题相比上一次简单不少 对编程新人或者刚开始学习算法的人很友好 前言 背景 本次CSDN编程
  • 服务器管理系统是什么

    服务器管理系统是什么 服务器管理系统 是在操作系统下对操作系统的服务器软件及其相关软件进行二次设置的管理软件 是运营商管理域名 服务器 企业邮局 数据库等服务器主机类产品的一个网站平台 以达到快捷实现域名 服务器主机 企业邮局 数据库等产品
  • C#连接数据库SQlServer+Form窗格实现简单动态增删查改操作

    C 连接数据库SQlServer Form窗格实现简单动态增删查改操作 一 数据库连接 数据库连接部分学习自该博主原创博客 点击即可跳转 再附上该博主的博客链接 https blog csdn net kiss soul article d
  • 深度学习去运动模糊----《DeblurGAN》

    前言 现实生活中 大多数图片是模糊不清的 试想一下 追剧时视频不清晰 看着都很捉急 何况现实中好端端的一幅美景 美女也可以 被抓拍得不忍直视 瞬间暴躁 拍照时手抖 或者画面中的物体运动都会让画面模糊 女友辛辛苦苦摆好的各种Pose也将淹没在
  • 海湾主机汉字注释表打字出_海湾报警主机(JB-QG-GST5000)操作手册

    报警主机正面示意图 报警主机内部结构图 控制器 模块总线 通讯总线 联动电源输出端子示意图 A1 B1 An Bn RS 485有极性通讯线端子 接火灾报警显示盘 GND 24V LD D02电源盘对外输出端子 保护地 此端子与机壳相连 接
  • NLP技术中的Tokenization

    作者 Gam Waiciu 单位 QTrade AI研发中心 研究方向 自然语言处理 前言 今天我们来聊一聊 NLP 技术中的 Tokenization 之所以想要聊这个话题 是因为 一方面在 NLP 技术中 Tokenization 是非
  • 网络知识:光纤收发器TX、RX介绍以及两者的区别

    当我们远距离传输时 通常会使用光纤来传输 因为光纤的传输距离很远 一般来说单模光纤的传输距离在10千米以上 而多模光纤的传输距离最高也能达到2千米 而在光纤网络中 我们常常会使用到光纤收发器 那么光纤收发器怎么连 我们一起来了解下 一 光纤
  • 自媒体月入过万的运营攻略,轻松上手

    很多自媒体新手羡慕大V月入过万 同是做自媒体运营 为什么自己不能实现营收过万呢 给大家分享一套月入过万的运营攻略 适合新手们去操作 收藏起来直接套用到运营哦 1 账号定位 清晰的定位是影响后期变现的关键因素 选一个后期容易变现的领域能帮自己
  • ajax net::err_connection_refused,javascript - How to handle net::ERR_CONNECTION_REFUSED in jquery aj...

    It appears that when jqXHR readyState i e the readyState field of the first parameter to the ajax fail method is 0 that
  • 调用织梦搜索功能

    织梦默认的搜索框
  • 使用C对TOML文件的解析

    使用C对TOML文件的解析 toml书写语法 解析toml文件 测试输出内容如下 TOML是前GitHub CEO Tom Preston Werner 于2013年创建的语言 其目标是成为一个小规模的易于使用的语义化配置文件格式 TOML