一文带你入门ini格式

引入:


以蜂鸣器为例,每次我们增加新的设备,


都需要添加两个新文件:


修改程序代码,手动添加:

缺点: 不利于维护

设备类节点直接通过ini文件配置


 什么是.ini文件


ini文件通常以纯文本形式存在,并且包含了一个或多个节(sections)以及每个节下的键值对(keyvalue pairs)。这些键值对用来指定应用程序的各种设置。
比如Linux系统里就有非常多这类格式的文件,如Linux下的打印机服务程序启动配置文
件/lib/systemd/system/cups.service:
 

举例:

cat /lib/systemd/system/dbus.service 


这种.server文件的格式就是 ini格式

[字段]
若干 键值对(key = value)

[sesction]
name = key

[Install]
Also=cups.socket cups.path
WantedBy=printer.target multi-user.target
 

在配置ini之前我们需要 安装ini文件对应的解析库 inih

inih解析库介绍

inih 是一个轻量级的 C 库,用于解析 INI 格式的配置文件。这个库由 Ben Hoyt 开发,并在 GitHub 上提供源 代码( https://github.com/benhoyt/inih )。 inih 库的设计目标是简单易用,同时保持最小的依赖性。

特点

以下是关于 inih 库的一些特点:
跨平台: inih 库是跨平台的,可以在多种操作系统和编译器环境下使用。
体积小: inih 库只有几个 C 文件,非常适合嵌入到其他项目中。
可定制:用户可以通过回调函数来处理读取到的键值对,使得处理方式非常灵活。
易于集成:只需要将 ini.c ini.h 两个文件添加到你的项目中即可开始使用。
支持注释: inih 库可以正确地处理以分号或哈希字符开头的行作为注释。
错误处理:如果在解析过程中遇到错误, ini_parse() 函数会返回一个负数。
要使用 inih 库,你需要在你的代码中包含 ini.h 头文件,并调用 ini_parse() 函数来解析 INI 文件。 ini_parse() 函数接受三个参数:要解析的文件名、一个回调函数以及一个用户数据指针。每当找到一个新的键值对 时,都会调用回调函数。

安装

apt-cache  search libinih

sudo apt install libinih-dev

方法二:

(博主方法一没下好,直接上Github下载)

直接到Github上面下载,然后通过FileZilla传送到虚拟机

下载zip文件 --> 解压  --> 传送得到这样一个文件夹

里面内容如下:

示例代码

查看C语言的示例代码

ini的简单使用:

新建一个 文件夹 -- ini

把前面我我们提到的ini.c , ini.h  文件创送过来

gdevice.ini

[lock]
key=0x44
gpio_pin=8
gpio_mode=OUTPUT
gpio_status=HIGH
check_face_status=1
voice_set_status=1[beep]
key=0x45
gpio_pin=9
gpio_mode=OUTPUT
gpio_status=HIGH
check_face_status=0
voice_set_status=1[BR led]
key=0x42
gpio_pin=5
gpio_mode=OUTPUT
gpio_status=HIGH
check_face_status=0
voice_set_status=0[LV led]
key=0x41
gpio_pin=2
gpio_mode=OUTPUT
gpio_status=HIGH
check_face_status=0
voice_set_status=0[fan]
key=0x43
gpio_pin=7
gpio_mode=OUTPUT
gpio_status=HIGH
check_face_status=0
voice_set_status=0

case1 -- 打印信息:

initest.c

/* Example: parse a simple configuration file */#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ini.h"#define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0static int handler(void* user, const char* section, const char* name,const char* value)
{printf("section = %s, name = %s, value = %s\n", section, name, value);return 1;
}int main(int argc, char* argv[])
{if (ini_parse("gdevice.ini", handler, NULL) < 0) {printf("Can't load 'gdevice.ini'\n");return 1;}return 0;
}

运行结果

case2 --  配置设备节点

其实就是把ini文件里面的设备消息,用头插法插入到对应的设备节点里面

initest.c

/* Example: parse a simple configuration file */#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ini.h"
#include "gdevice.h"// 没引入wiringpi库要手动定义宏#ifndef LOW
#define LOW 0
#define  HIGH 1
#endif#ifndef OUTPUT
#define OUTPUT 1
#define INPUT 0
#endif#define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0static struct gdevice *pdevhead = NULL;static int handler_gdevice(void* user, const char* section, const char* name,const char* value)
{struct gdevice *pdev = NULL;if(NULL ==  pdevhead){pdevhead = (struct gdevice *)malloc(sizeof(struct gdevice));memset(pdevhead, 0, sizeof(struct gdevice));pdevhead->next = NULL;strcpy(pdevhead->dev_name,section);     }//printf("section = %s, name = %s, value = %s\n", section, name, value);else if(0 != strcmp(section, pdevhead->dev_name))// 当section对不上的时候,表示到了下一个设备{// 把新节点(设备)使用头插法插入pdev = (struct gdevice *)malloc(sizeof(struct gdevice));memset(pdev, 0, sizeof(struct gdevice));strcpy(pdev->dev_name,section);pdev->next = pdevhead;pdevhead = pdev;}if(NULL != pdevhead){if(MATCH(pdevhead->dev_name, "key")){sscanf(value, "%x", &pdevhead->key); //把value(string)的值 转为int类型 16进行格式 传递给  pdevhead->key)printf("%d  pdevhead->key = 0x%x\n",__LINE__,pdevhead->key);}else if(MATCH(pdevhead->dev_name, "gpio_pin")){pdevhead->gpio_pin = atoi(value);}else if(MATCH(pdevhead->dev_name, "gpio_mode")){if(strcmp(value, "OUTPUT") == 0){pdevhead->gpio_mode = OUTPUT;}else if(strcmp(value, "INPUT") == 0){pdevhead->gpio_mode = INPUT;}else{printf("gpio_mode error\n");}}else if(MATCH(pdevhead->dev_name, "gpio_status")){if(strcmp(value, "LOW") == 0){pdevhead->gpio_mode = LOW;}else if(strcmp(value, "HIGH") == 0){                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       pdevhead->gpio_mode = HIGH;}else{printf("gpio_status error\n");}}else if(MATCH(pdevhead->dev_name, "check_face_status")){pdevhead->check_face_status = atoi(value);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        }else if(MATCH(pdevhead->dev_name, "voice_set_status")){pdevhead->voice_set_status     = atoi(value);}}return 1;
}int main(int argc, char* argv[])
{struct gdevice *pdev = NULL;//printf("before handler_gdevice %d",__LINE__);if (ini_parse("gdevice.ini", handler_gdevice, NULL) < 0) {printf("Can't load 'gdevice.ini'\n");return 1;}//printf("after handler_gdevice %d",__LINE__);//打印每个设备的信息来测试是否配置成功pdev = pdevhead;while (pdev != NULL){//printf("inside %d",__LINE__);printf("dev_name:%s\n",pdev->dev_name);printf("key:%x\n",pdev->key);printf("gpio_pin:%d\n",pdev->gpio_pin);printf("gpio_mode:%d\n",pdev->gpio_mode);printf("gpio_status:%d\n",pdev->gpio_status);printf("check_face_status:%d\n",pdev->check_face_status); printf("voice_set_status:%d\n",pdev->voice_set_status);pdev= pdev->next;}return 0;
}

运行结果

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

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

相关文章

java技术:spring-secrity实现认证、授权

目录 一、依赖 二、逻辑图 三、代码设计 1、WebSecurityConfigurerAdapter的实现类 2、设计登录接口 config配置&#xff1a; 1&#xff09;UserDetailsService实现类重写&#xff1a; 2&#xff09;书写登录实现类&#xff08;调用authenticationManager、可以与后面的…

重新夺回控制权!原创始人从Synk回购FossID,致力于解决开源许可合规风险

FossID 于 2022 年 9 月被其原始创始人从 Snyk, Inc. 重新收购。为什么 Snyk 在 2021 年收购了 FossID&#xff0c;又在 2022 年将其分拆&#xff0c;以及为什么 FossID 的创始人&#xff08;Oskar Swirtun 和 Jon Aldama&#xff09;后来又回购了该公司&#xff1f; 公司背景 …

类和对象的基本概念

类和对象的基本概念 C和C中struct区别类的封装封装访问权限总结struct和class的区别 将成员变量设置为private C和C中struct区别 C语言struct只有变量C语言struct 既有变量&#xff0c;也有函数 类的封装 封装 把变量&#xff08;属性&#xff09;和函数&#xff08;操作&a…

Undet for SketchUp 2023.3 点云建模软件 支持支持草图大师sketchup2021-2022-2023

1.Undet for sketchup 2023.3支持草图大师sketchup2021-2022-2023。支持机载雷达扫描、车载扫描还是地面扫描&#xff0c;对AEC行业用户来说&#xff0c;真正需要的是如何将这些数据快速处理为三维模型&#xff0c;这样才能将这些信息延展到BIM领域发挥效用。因此面对这些海量的…

Go源码--sync库(1)sync.Once和

简介 这篇主要介绍 sync.Once、sync.WaitGroup和sync.Mutex sync.Once once 顾名思义 只执行一次 废话不说 我们看源码 英文介绍直接略过了 感兴趣的建议读一读 获益匪浅 其结构体如下 Once 是一个严格只执行一次的object type Once struct {// 建议看下源码的注解&#xf…

python:pycharm虚拟解释器报错环境位置目录为空

目录 解释器分控制台解释器 和 pycharm解释器 控制台解释器切换&#xff1a; pycharm解释器 解释器分控制台解释器 和 pycharm解释器 控制台解释器切换&#xff1a; 切换到解释器下 激活解释器 查看解释器 where python 激活成功 这时在控制台使用python xxx.py 可以…

表现层框架设计之表现层设计模式_3.MVVM模式

1.MVVM模式 MVVM模式正是为解决MVP中UI种类变多&#xff0c;接口也会不断增加的问题而提出的。 MVVM模式全称是模型-视图-视图模型&#xff08;Model-View-ViewModel&#xff09;&#xff0c;它和MVC、MVP类似&#xff0c;主要目的都是为了实现视图和模型的分离&#xff0c;不…

Flink 生态对 Confluent / Kafka Schema Registry 支持情况的研究报告

文章目录 1. Flink CDC 对 Confluent Schema Registry 的支持情况2. Confluent Avro Format 对 Confluent Schema Registry 的支持情况3. 关键性结论 这几年&#xff0c;在流式链路上引入一个 Schema Registry 变得越来越流行&#xff0c;也越来越有必要&#xff0c; Schema Re…

信息化项目交付验收流程管理办法

项目交付验收流程制度 管理办法 (执行版) (文件编号: ) 编制: 审核: 批准: 版本: 生效日期: 管理办法概述 制定目的为了保证公司在建项目交付验收工作事项的顺利开展,保证交付验收进度及…

舵机(结构,原理,控制方法)

介绍 舵机&#xff0c;全称为伺服马达&#xff08;Servo Motor&#xff09;&#xff0c;是一种能够精确控制角度或位置的电动机。它广泛应用于模型制作、机器人技术、工业自动化等领域。舵机通过接收控制信号&#xff0c;将其转化为机械运动&#xff0c;从而实现精确的控制。 …

211初试自命题复试线仅302分!延边大学计算机考研考情分析!

延边大学&#xff08;Yanbian University&#xff09;&#xff0c;简称“延大”&#xff0c;地处吉林省延边朝鲜族自治州&#xff0c;是国家“双一流”建设高校、国家“211工程”重点建设大学、西部开发重点建设院校、吉林省人民政府和教育部共同重点支持建设大学、吉林省人民政…

pcd点云江湖之处处碰壁:点云文件pcd加载02

江湖好汉&#xff0c;休走&#xff0c;废了半天力气把threejs自带的代码搬迁到自己项目中了&#xff0c;高高兴兴给领导看。领导一句话&#xff0c;顿时无奈&#xff1a;领导曰&#xff1a;点云单色太丑&#xff0c;能不能按照分类展示&#xff1f; 一句话难道英雄好汉&#xf…

IT廉连看——UniApp——事件绑定

IT廉连看——UniApp——事件绑定 这是我们上节课最终的样式&#xff1b; 一、现在我有这样一个需求&#xff0c;当我点击“生在国旗下&#xff0c;长在春风里”它的颜色由红色变为蓝色&#xff0c;该怎么操作&#xff1f; 这时候我们需要一个事件的绑定&#xff0c;绑定一个单…

【webrtc】m98:Call的创建及Call对音频接收处理

call中多個流共享相同的辅助组件 这几个是与外部共用的 线程传输send控制module 线程任务队列工厂call的辅助组件中各种统计以及接收测的cc是自己创建的 call自己的多个辅助组件是外部传递来的 call 创建多个接收流 这里用一个set 来保存所有指针,并没有要map的意思:

debian nginx upsync consul 实现动态负载

1. consul 安装 wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg echo "deb [signed-by/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_r…

本是梦中人,常作花下客。心中自往来,知我有几个。

我们总是喜欢拿“顺其自然”来敷衍人生道路上的荆棘坎坷&#xff0c;却很少承认&#xff0c;真正的顺其自然&#xff0c; 其实是竭尽所能之后的不强求&#xff0c; 而非两手一摊的不作为。 一花凋零荒芜不了整个春天&#xff0c; 一次挫折也荒废不了整个人生。 多年后&#x…

GQL 来了!ISO/IEC 正式发布 GQL 数据库国际标准!

历时四年筹备&#xff0c;超过20个国家的标准和技术专家参与制定&#xff0c;ISO/IEC GQL &#xff08;图查询语言&#xff09;标准于2024年4月12日正式发布&#xff01; 作为国际标准化组织&#xff08;ISO&#xff09;继 1987年 发布SQL后&#xff0c;唯一发布的数据库查询语…

【数据结构】哈夫曼树和哈夫曼编码

一、哈夫曼树 1.1 哈夫曼树的概念 给定一个序列&#xff0c;将序列中的所有元素作为叶子节点构建一棵二叉树&#xff0c;并使这棵树的带权路径长度最小&#xff0c;那么我们就得到了一棵哈夫曼树&#xff08;又称最优二叉树&#xff09; 接下来是名词解释&#xff1a; 权&a…

Vue 3 的 setup语法糖工作原理

前言 我们每天写vue3项目的时候都会使用setup语法糖&#xff0c;但是你有没有思考过下面几个问题。setup语法糖经过编译后是什么样子的&#xff1f;为什么在setup顶层定义的变量可以在template中可以直接使用&#xff1f;为什么import一个组件后就可以直接使用&#xff0c;无需…