使用C对TOML文件的解析

  • toml书写语法
  • 解析toml文件
  • 测试输出内容如下

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);elseprintf("]\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:xxx1:xxx1:0:xxx1:xxx1:0:0:xxx1:xxx1:0:xxx1: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 = 50000Timeout = 5000ConnectRetries = 10Labels = [ '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 = falseDiscovery = falseMaxCmdOps = 128MaxCmdResultLen = 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 = 9600DataBits = 8StopBits = 1Parity = 'N'UnitID = 1[[DeviceList.AutoEvents]]Resource = 'temperature'OnChange = falseFrequency = '10s'[[DeviceList.AutoEvents]]Resource = 'humidity'OnChange = trueFrequency = '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 = 9600DataBits = 8StopBits = 1Parity = 'N'UnitID = 2[[DeviceList.AutoEvents]]Resource = 'temperature'OnChange = falseFrequency = '10s'[[DeviceList.AutoEvents]]Resource = 'humidity'OnChange = trueFrequency = '15000ms'
gcc toml.c test.c -o test
#增加执行权限
sudo chmod +x test
#运行解析
./test sample.toml

测试输出内容如下

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

  1. c语言解析toml文件,使用BurntSushi/toml处理项目中toml格式的配置文件

    一.简介 配置文件有很多种类,比如.ini.xml.json.YAML再到TOML,TOML 的全称是 Tom's Obvious, Minimal Language,因为它的作者是 GitHub 联 ...

  2. Python读写TOML文件

    文章目录 TOML介绍 Python读写TOML 安装toml解析包 函数说明 toml.load(f, _dict=dict) 参数 返回 异常 toml.loads(s, _dict=dict) ...

  3. Golang输出toml文件时保留原toml注释

    有这样一种使用场景,Golang从文件或字符串中读取toml数据并解析,然后进行相应的修改,最后重新写回到文件中,由于一般的toml库不会去特别处理注释,重新生成的toml文件中所有原始的注释都会丢失 ...

  4. 常用配置文件-toml文件

    toml的目标是成为一种最小的配置文件格式,由于明显的语义,该格式易于阅读.toml旨在明确的映射到哈希表.toml应该易于解析解析为多重语言的数据结构. .toml文件的基本格式如下: [defau ...

  5. Office文件的奥秘——.NET平台下不借助Office实现Word、Powerpoint等文件的解析(完)...

    原文 http://www.cnblogs.com/mayswind/archive/2013/04/01/2991271.html [题外话] 这是这个系列的最后一篇文章了,为了不让自己觉得少点什么 ...

  6. pandas使用read_csv函数读取文件并解析日期数据列(parse dates)、pandas使用read_csv函数读取文件并将缺失值转化为空字符串

    pandas使用read_csv函数读取文件并解析日期数据列(parse dates).pandas使用read_csv函数读取文件并将缺失值转化为空字符串 目录

  7. INI文件快速解析java工具包

    FastIni 概述 相信大家都用过阿里的fastjson,它可以通过模板快速解析json字符串,也可以通过key快速获取json字符串中的值.通过模板类型快速解析json字符串是一个很好的想法,所以 ...

  8. C语言文件操作解析(二)【转载】

    http://www.cnblogs.com/dolphin0520/archive/2011/10/05/2199598.html C语言文件操作解析(二) C语言中对文件进行操作必须首先打开文件, ...

  9. mybatis中config.xml文件的解析

    config.xml文件的解析是主要是XMLConfigBuilder完成的,通过调用parseConfiguration来实现整个解析过程 public Configuration parse() ...

最新文章

  1. [微信小程序]提交表单返回成功后自动清空表单的值
  2. R语言ggplot2可视化柱状图并自定义柱体的宽度(通过变量指定条形的宽度)实战、条形图并自定义条形的宽度实战
  3. iOS APP提交上架最新流程(转)
  4. LaTeX Test
  5. 分享几款比较常用的代码比较工具
  6. 网站性能优化的三重境界
  7. 黄聪:【强烈推荐】搜索引擎排名决定一切吗!
  8. 自适应移动设备页面的设计
  9. Spring Boot + Log4j2 日志框架配置 (Maven)
  10. html2canvas截图地图和看到的不一样_大秦赋,我看到的不一样的赢异人。
  11. 491. 递增子序列
  12. 为什么单独循环中的元素加法比组合循环中的要快得多?
  13. Mac 安装 MySQL 教程
  14. python内点法_最优化问题(三) 之 外点法(罚函数法)
  15. 一键Pad变电脑,安全快速的远控办公这不就来了。
  16. idea打包jar程序
  17. 流程图与算法_流程图与算法之间的区别
  18. 智能合约漏洞检测论文整理
  19. 【计算机-CPU】电子电路-机器语言与指令集架构/CPU软核/CPU硬核-汇编语言与与编译器
  20. python中如何将矩阵合并并多一个维度

热门文章

  1. 牛客小白66 A-F
  2. java文件下载时如何解决中文名称不显示的问题
  3. 生产制造企业中电子工艺看板设计与实现
  4. WIN10缺少MSVCR相关的动态库
  5. 程序员每天工作多少个小时_程序员每天实际工作几个小时?
  6. 狂神说-Docker
  7. Redis的数据删除策略
  8. redis底层数据结构 -String
  9. NGS测序基础梳理01-文库构建(Library Preparation)
  10. Linux 帮助指令(man、help、info)