分享

嵌入式大杂烩周记 | 第 10 期

 嵌入式大杂烩 2022-04-14

大家好,我是杂烩君。

嵌入式大杂烩周记主要是一些实用项目学习分享,每周一篇,每篇一个主题。

内容主要来源于我们之前收集的资料:

https:///zhengnianli/EmbedSummary

本期主角:inih

inih:一个C 语言编写的 INI 文件解析器。配置文件的格式有很多,如JSON、INI等。

JSON之前分享过了:例说嵌入式实用知识之JSON数据

本次我们使用inih解析器对ini格式配置文件的解析。

inih解析器源码地址:

作者:benhoyt

链接:https://github.com/benhoyt/inih

inih的使用

.ini 文件是 Initialization File 的缩写,即初始化文件。INI文件由节、键、值组成,注解使用分号表示(;)。例如:

[Section1 Name]
KeyName1_1=value1_1  ;这是注释
KeyName1_2=value1_2
[Section2 Name]
KeyName2_1=value2_1
KeyName2_2=value2_2

之前分享的嵌入式大杂烩周记 | 第 2 期:LLGUI中的配置文件也是INI格式。

从上面的源码仓库下载得到代码:

下面我们在我们的配置文件里记录IP等信息,应用代码解析INI配置文件得到IP并使用。

ini.cini.h 放到我们的工程下即可。这里我们使用一个测试工程:

同时,新建一个 ip.ini 文件存放于工程目录下。ip.ini 文件的内容如:

[ip]                ;Section1
ip_addr = 192.168.1.103

[test]              ;Section2
name = ZhengN       
num  = 66  

下面我们编写代码test.c来解析这个文件:

// 微信公众号:嵌入式大杂烩
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ini.h"

typedef struct
{

    const char* ip_addr;
    const char* name;
    int num;
} configuration;

static int handler(void* user, const char* section, const char* name,
                   const char* value)

{
    configuration* pconfig = (configuration*)user;

    #define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0
    if (MATCH("ip""ip_addr")) 
    {
        pconfig->ip_addr = strdup(value);
    } 
    else if (MATCH("test""name")) 
    {
        pconfig->name = strdup(value);
    } 
    else if (MATCH("test""num")) 
    {
        pconfig->num = atoi(value);
    } 
    else 
    {
        return 0;  /* unknown section/name, error */
    }

    return 1;
}

int main(int argc, char* argv[])
{
    configuration config;
    config.ip_addr = NULL;  /* set defaults */
    config.name = NULL;
    config.num = 0;

    if (ini_parse("ip.ini", handler, &config) < 0
    {
        printf("Can't load 'ip.ini'\n");
        return 1;
    }
    printf("Config loaded from 'ip.ini': ip_addr = %s, name = %s, num = %d\n",
        config.ip_addr, config.name, config.num);

    if (config.ip_addr)
        free((void*)config.ip_addr);
    if (config.name)
        free((void*)config.name);

    return 0;
}

解析方法很简单(可参考 inih/examples 下的demo,我们这里也是模仿这个demo来做解析的):

  • 构造一个配置结构体 configuration ,定义一个configuration结构体用于保存我们解析的数据,结构体里面的成员就是我们需要解析的INI文件里的各个键。例如,我们的ip.ini文件里有ip_addr、name、num这三个键,结构体里的成员表示的就是这三个键。

  • 定义一个handler回调函数,用于处理解析过程。解析过程也很简单,匹配Section Name及Key Name,然后取出值即可。

  • 调用 ini_parse 函数对INI文件进行解析。

其中,handler函数里调用了一个 strdup() 函数及 atoi() 函数。

  • strdup()函数是c语言中常用的一种字符串拷贝库函数,一般和free()函数成对出现,,因为strdup()在内部调用了malloc()函数为变量分配内存。
  • atoi()函数(ascii to integer)是把字符串转换成整型数的一个函数。

编译、运行:

如果觉得文章有帮助,麻烦帮忙点赞、收藏、转发,谢谢!

咱们下期见~

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多