一文带你入门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) == 0

static 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) == 0


static 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;
}

运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值