99久久全国免费观看_国产一区二区三区四区五区VM_久久www人成免费看片中文_国产高清在线a视频大全_深夜福利www_日韩一级成人av

一文告訴你Linux下如何用C語言實(shí)現(xiàn)ini配置文件的解析和保存

嵌入式項目開發(fā)中,會有很多功能模塊需要頻繁修改參數(shù),Linux下我們可以通過ini格式的文件保存配置信息。

本文通過開源庫iniparser,詳細(xì)講解如何用C語言實(shí)現(xiàn)ini文件的參數(shù)解析和配置保存。

本文代碼實(shí)例獲取方式見文末。

一、ini文件

1 什么是 ini文件

INI(Initialization File)文件是一種簡單直觀的數(shù)據(jù)存儲格式,常用于配置應(yīng)用程序的初始化設(shè)置。這種文件通常包含若干個節(jié)(section)和鍵值對(key-value pairs)。 INI文件的每一部分都是自描述性的,易于閱讀和編輯,使得非程序員也能輕易理解并修改配置參數(shù)。

INI文件因其簡單易用性而在許多編程語言中廣泛應(yīng)用,尤其是在Windows操作系統(tǒng)中,很多應(yīng)用程序都采用INI文件作為配置文件。 當(dāng)然,隨著XML、JSON等更豐富、更結(jié)構(gòu)化的數(shù)據(jù)交換格式的普及,INI文件在現(xiàn)代應(yīng)用程序中的使用相對減少,但在一些輕量級應(yīng)用或?qū)铀俣扔休^高要求的情況下,仍然是一種常見且實(shí)用的配置文件格式。

2 ini文件結(jié)構(gòu)

節(jié)(Section)

INI文件中的各個部分通過方括號 [] 包裹的名稱來定義,例如 **[Section1]**。每個節(jié)可以包含多個鍵值對。

鍵值對(Key-Value Pairs)

鍵和值之間用等號 = 分隔,如 key1=value1。鍵通常是描述性質(zhì)的字符串,而值則可以是字符串、數(shù)字或其他類型的數(shù)據(jù)。

注釋

注釋行以分號 ; 開始,直到行尾都被視為注釋內(nèi)容,不會被程序解析。

多行值

某些INI解析器允許值跨越多行,通常通過在行尾添加反斜杠 \ 來延續(xù)到下一行

3 ini文件舉例

;author yikoupeng[BASIC_INFO]version                = V1.1.1.1user                   = yikounumber                 = 999[FTP]ftppath                = /home/ftpftpuser                = ftpftppass                = 123456port                   = 21......

其中:

  • 注釋以分號(;)開頭
  • [BASIC_INFO]、[FTP]就是組名,
  • 組成員有“version”........“ftppath”...

注意:

每個組下的key是唯一不能重復(fù)的,但不同組下可以存在相同的key.

二、 iniparser庫

1. iniparser介紹

iniparser是一個C語言庫,用于解析和操作 INI 格式的配置文件,是針對INI文件的開源解析器。

iniparser可以對配置文件進(jìn)行解析、添加、修改、刪除等操作。

git地址如下:

https://github.com/ndevilla/iniparser

2. iniparser的安裝

1、下載iniparser

wget https://codeload.github.com/ndevilla/iniparser/tar.gz/refs/tags/v4.1 -O iniparserv4.1.tar.gz

2、解壓

tar -zxvf iniparserv4.1.tar.gz  
cd iniparser-4.1/
peng@ubuntu:~/work/iniparser-4.1$ lsAUTHORS  doc  example  FAQ-en.md  FAQ-zhcn.md  html  INSTALL  libiniparser.a  libiniparser.so.1  LICENSE  Makefile  README.md  src  test

3、進(jìn)入目錄

4、進(jìn)入src文件夾可以看到我們所需要的主要代碼

peng@ubuntu:~/work/iniparser-4.1$ cd src/peng@ubuntu:~/work/fdw/code/config/iniparser-4.1/src$ lsdictionary.c  dictionary.h   iniparser.c  iniparser.h 

如果想移植該程序到我們的項目中,只需要將這幾個文件添加到工程對應(yīng)目錄,編譯進(jìn)工程即可。

三、iniparser API(應(yīng)用編程程序接口)

dictionary.h里面聲明了一些直接解析ini file的API,iniparser.h頭文件里面聲明了一些提供用戶操作的API。

iniparser.h里面的API是對dictionary.h里面API的再次封裝,以提供用戶友好性。

iniparser.h頭文件里面的主要API

1 加載ini文件

/*   *  @brief  從ini格式的配置文件中加載數(shù)據(jù)   *  @param  [IN]  ininame  要打開的ini格式文件               *  @return != NULL 返回一個指向dictionary結(jié)構(gòu)的指針   *          == NULL 加載ini文件失敗  */  dictionary * iniparser_load(const char *ininame);

2 獲取鍵值

  /*   *  @brief  獲取指定鍵(key)對應(yīng)的字符串類型的值   *  @param  [IN]  d  dictionary結(jié)構(gòu)的指針      *  @param  [IN]  key  要查找的鍵,通常格式為 "section:key",表示要獲取哪個節(jié)(section)下的哪一項(key)的值。   *  @param  [IN]  def  當(dāng)鍵不存在或者其值不是字符串時的默認(rèn)返回值。如果沒有找到對應(yīng)鍵,函數(shù)將返回此默認(rèn)值。       *  @return 如果找到了相應(yīng)的鍵,返回鍵值對應(yīng)字符串   *    如果沒有找到匹配的鍵,返回def指定的字符串值  */  const char * iniparser_getstring(const dictionary *d, const char *key, const char *def);  /*  *  @brief  獲取指定鍵(key)對應(yīng)的整數(shù)值  *  @param  [IN]  d  dictionary結(jié)構(gòu)的指針     *  @param  [IN]  key  要查找的鍵,通常格式為 "section:key",表示要獲取哪個節(jié)(section)下的哪一項(key)的值。  *  @param  [IN]  notfound  當(dāng)鍵不存在或者其值不能被轉(zhuǎn)換為整數(shù)時,函數(shù)將返回這個默認(rèn)值。     *  @return 如果找到了相應(yīng)的鍵,并且其值可以被成功轉(zhuǎn)換為整數(shù),則返回該整數(shù)值。  *     如果沒有找到匹配的鍵,或者該鍵對應(yīng)的值無法轉(zhuǎn)換為整數(shù),則返回 notfound 參數(shù)提供的默認(rèn)值。  */  int iniparser_getint(const dictionary * d, const char * key, int notfound);  /*  *  @brief  獲取指定鍵(key)對應(yīng)的浮點(diǎn)型值  *  @param  [IN]  d  dictionary結(jié)構(gòu)的指針     *  @param  [IN]  key  要查找的鍵,通常格式為 "section:key",表示要獲取哪個節(jié)(section)下的哪一項(key)的值。  *  @param  [IN]  notfound  當(dāng)鍵不存在或者其值無法轉(zhuǎn)換為雙精度浮點(diǎn)數(shù)時,函數(shù)返回的默認(rèn)值。  *  @return 如果找到了相應(yīng)的鍵,并且其值能成功轉(zhuǎn)換為一個雙精度浮點(diǎn)數(shù),則返回該浮點(diǎn)數(shù)。  *     如果沒有找到匹配的鍵,或者鍵的值不能被解釋為一個有效的雙精度浮點(diǎn)數(shù),則返回 notfound 參數(shù)所提供的默認(rèn)值。  */  double iniparser_getdouble(const dictionary *d, const char *key, double notfound);

3 設(shè)置鍵值

/*  *  @brief  設(shè)置或修改 ini  配置文件中某個鍵值對  *  @param  [IN]  d  dictionary結(jié)構(gòu)的指針     *  @param  [IN]  entry  字符串形式的鍵值對標(biāo)識符,格式通常是 "section:key",表明您要在哪個節(jié)(section)下的哪個鍵(key)上設(shè)置或修改值(val)。  *      key值存在則修改對應(yīng)val,key值不存在則會新增  *  @param  [IN]  val: 要設(shè)置的新值,作為字符串傳遞。  *  @return 返回0表示設(shè)置成功  */  int iniparser_set(dictionary *ini, const char *entry, const char *val);

4 移除鍵值

/**  @brief  移除 ini 配置文件中某個鍵值對*  @param  [IN]  d  dictionary結(jié)構(gòu)的指針   *  @param  [IN]  entry  字符串形式的鍵名,包括可選的部分名稱(section)和鍵(key)*          如果不指定key,則會移除整個section*/void iniparser_unset(ini, const char *entry);

5 判斷鍵是否存在

/**  @brief  判斷 ini 配置文件是否存在某個鍵值*  @param  [IN]  d  dictionary結(jié)構(gòu)的指針   *  @param  [IN]  entry  字符串形式的鍵值對標(biāo)識符,格式通常是 "section:key"*  @return 返回1表示存在,返回0表示不存在*/int iniparser_find_entry(const dictionary *ini, const char *entry);

6 獲取section個數(shù)

/**  @brief  獲取ini配置文件中section的數(shù)量*  @param  [IN]  d  dictionary結(jié)構(gòu)的指針             *  @return 成功返回section個數(shù),失敗返回 -1*/int iniparser_getnsec(const dictionary * d);  /**  @brief  獲取某個section值*  @param  [IN]  d  dictionary結(jié)構(gòu)的指針*  @param  [IN]  n  指定獲取第幾個section值                  *  @return 成功返回獲取到的section值,失敗返回NULL*/const char *iniparser_getsecname(const dictionary * d, int n);

7 獲取section下key個數(shù)

/**  @brief  獲取ini配置文件中某個section的key個數(shù)*  @param  [IN]  d  dictionary結(jié)構(gòu)的指針 *  @param  [IN]  s  section          *  @return 返回指定section下的key個數(shù)*/int iniparser_getsecnkeys(dictionary * d, char * s);   /**  @brief  獲取ini配置文件中某個section的所有key*  @param  [IN]  d  dictionary結(jié)構(gòu)的指針 *  @param  [IN]  s  section      *  @param  [OUT]  keys  通過這個參數(shù)輸出key,也可以通過返回值獲取     *  @return  成功返回指定section下的key,失敗返回NULL*/const char **iniparser_getseckeys(const dictionary *d, const char *s, const char **keys)

8 保存dictionary對象到文件中

/**  @brief  保存dictionary對象到文件中*  @param  [IN]  d  dictionary結(jié)構(gòu)的指針   *  @param  [IN]  f  已打開的文件描述符*/void iniparser_dump_ini(const dictionary *d, FILE *f);

9 釋放dictionary對象

/**  @brief  釋放dictionary對象*  @param  [IN]  d  dictionary結(jié)構(gòu)的指針   */void iniparser_freedict(dictionary * d);

10 api匯總

  • iniparser.h頭文件里面的API
//獲取dictionary對象的section個數(shù)  int iniparser_getnsec(dictionary * d);   //獲取dictionary對象的第n個section的名字  char * iniparser_getsecname(dictionary * d, int n); //保存dictionary對象到file  void iniparser_dump_ini(dictionary * d, FILE * f);  //保存dictionary對象一個section到filevoid iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f);   //保存dictionary對象到file void iniparser_dump(dictionary * d, FILE * f);  //獲取dictionary對象某個section下的key個數(shù) int iniparser_getsecnkeys(dictionary * d, char * s);  //獲取dictionary對象某個section下所有的keychar ** iniparser_getseckeys(dictionary * d, char * s);   //返回dictionary對象的section:key對應(yīng)的字串值  char * iniparser_getstring(dictionary * d, const char * key, char * def);  //返回idictionary對象的section:key對應(yīng)的整形值  int iniparser_getint(dictionary * d, const char * key, int notfound); //返回dictionary對象的section:key對應(yīng)的雙浮點(diǎn)值  double iniparser_getdouble(dictionary * d, const char * key, double notfound);   //返回dictionary對象的section:key對應(yīng)的布爾值  int iniparser_getboolean(dictionary * d, const char * key, int notfound);  //設(shè)置dictionary對象的某個section:key的值  int iniparser_set(dictionary * ini, const char * entry, const char * val); //刪除dictionary對象中某個section:keyvoid iniparser_unset(dictionary * ini, const char * entry);  //判斷dictionary對象中是否存在某個section:keyint iniparser_find_entry(dictionary * ini, const char * entry) ;   //解析dictionary對象并返回(分配內(nèi)存)dictionary對象dictionary * iniparser_load(const char * ininame);//釋放dictionary對象(內(nèi)存)  void iniparser_freedict(dictionary * d);    
  • dictionary.h頭文件里面的API
 //計算關(guān)鍵詞的hash值unsigned dictionary_hash(const char * key); //創(chuàng)建dictionary對象dictionary * dictionary_new(int size);   //刪除dictionary對象void dictionary_del(dictionary * vd);   //獲取dictionary對象的key值char * dictionary_get(dictionary * d, const char * key, char * def); //設(shè)置dictionary對象的key值int dictionary_set(dictionary * vd, const char * key, const char * val); //刪除dictionary對象的key值void dictionary_unset(dictionary * d, const char * key); //保存dictionary對象void dictionary_dump(dictionary * d, FILE * out);    

四、 iniparser庫C語言操作實(shí)例

1、config.ini

編寫配置文件:

vim config.ini
[BASIC_INFO]version                        = V1.1.1.1user                           = yikounumber                         = 999[FTP]ftppath                        = /home/ftpftpuser                        = ftpftppass                        = 123456port                           = 21[NETWORK]interface                      = eth1dns1                           = 8.8.8.8dns2                           = 8.8.8.8subnet                         = 255.255.255.0router                         = 192.168.3.1

2、讀取配置參數(shù)

嘗試編寫iniparser程序?qū)ni文件進(jìn)行修改:

#include #include "iniparser.h"#include "dictionary.h"#define PATH "config.ini"typedef unsigned char BYTE;typedef unsigned char UINT8;typedef unsigned char UCHAR;typedef unsigned short int UINT16;typedef unsigned long int UINT32;struct device_cfg_s{/*basicinfo*/  char version[32]; char user[32]; int number;/*ftp*/  char ftppath[128]; char ftpuser[32]; char ftppass[32]; UINT16 port;/*network*/  char interface[16]; char dns1[32];    char dns2[32];    char subnet[32];    char router[32]; };struct device_cfg_s devcfg;int cfg_load(char *name){    dictionary *ini= NULL;    /* 解析dictionary對象并返回(分配內(nèi)存)dictionary對象*/    ini = iniparser_load(name);    if( ini ==NULL)    {        printf("iniparser  failure\n");        return -1;    } /*basicinfo*/ strcpy(devcfg.version,iniparser_getstring(ini, "BASIC_INFO:version", "v0.0.0.0")); strcpy(devcfg.user ,iniparser_getstring(ini, "BASIC_INFO:user", "yikou")); devcfg.number = iniparser_getint(ini, "BASIC_INFO:number", 666); /*ftp*/  strcpy(devcfg.ftppath ,iniparser_getstring(ini, "FTP:ftppath", "/")); strcpy(devcfg.ftpuser ,iniparser_getstring(ini, "FTP:ftpuser", "ftp")); strcpy(devcfg.ftppass ,iniparser_getstring(ini, "FTP:ftppass", "123456")); devcfg.port = iniparser_getint(ini, "FTP:port", 21);  /*network*/  strcpy(devcfg.interface,iniparser_getstring(ini, "NETWORK:interface", "eth0")); strcpy(devcfg.dns1,iniparser_getstring(ini, "NETWORK:dns1", NULL)); strcpy(devcfg.dns2 ,iniparser_getstring(ini, "NETWORK:dns2", NULL)); strcpy(devcfg.subnet ,iniparser_getstring(ini, "NETWORK:subnet", "255.255.255.0")); strcpy(devcfg.router ,iniparser_getstring(ini, "NETWORK:router", "192.168.3.1"));     /* 返回dictionary對象的section,key對應(yīng)的字串值 */    printf("version:%s\n",devcfg.version);    printf("user:%s\n", devcfg.user);    printf("number:%d\n",devcfg.number);     printf("ftppath:%s\n", devcfg.ftppath);    printf("ftpuser:%s\n",devcfg.ftpuser);    printf("ftppass:%s\n", devcfg.ftppass);    printf("port:%d\n",devcfg.port);     printf("interface:%s\n", devcfg.interface);    printf("dns1:%s\n",devcfg.dns1);    printf("dns2:%s\n", devcfg.dns2);    printf("subnet:%s\n",devcfg.subnet);    printf("router:%s\n", devcfg.router);    iniparser_freedict(ini);}int main (int argc, char **argv){ cfg_load(PATH); //cfg_save_key(PATH,"BASIC_INFO","chnAddr","3501"); //cfg_save_key(PATH,"BASIC_INFO","enddeviceNo","87564289");    return 0;}

int cfg_save_key(char *filename,char *section,char *key,char *value)參數(shù):    filename  配置文件名    section   節(jié)名字    key       鍵    value     值
int cfg_save_key(char *filename,char *section,char *key,char *value){ FILE  *fp = NULL  ; dictionary *ini= NULL; char item[128]={0};  /* 解析dictionary對象并返回(分配內(nèi)存)dictionary對象*/ ini = iniparser_load(filename); if( ini ==NULL) {  printf("iniparser  failure\n");  return -1; } sprintf(item,"%s:%s",section,key);  /* 設(shè)置dictionary對象的某個section:key的值 */ iniparser_set(ini, item, value); fp = fopen(filename, "w"); if( fp == NULL ) {  printf("stone:fopen error!\n");  exit(-1); } /* 保存dictionary對象 */ //   iniparser_dumpsection_ini(ini, "BASIC_INFO", fp); iniparser_dump_ini(ini, fp); fclose(fp); /* 釋放dictionary對象(內(nèi)存)*/ iniparser_freedict(ini);}

可以看到最終值以配置文件中的為準(zhǔn)。

如果配置文件沒有配置參數(shù)則以iniparser_getxxxxx()中默認(rèn)值為準(zhǔn)。

3、保存配置信息到文件

為方便保存鍵值,彭老師封裝了函數(shù)

例如我們修改BASIC_INFO節(jié)的user的值為yikoupengnumber值為12345

 cfg_save_key(PATH,"BASIC_INFO","user","yikoupeng"); cfg_save_key(PATH,"BASIC_INFO","number","12345");

執(zhí)行結(jié)果:

可以看到配置文件basic_info節(jié)的usernumber 鍵值對被修改。

聲明:本內(nèi)容為作者獨(dú)立觀點(diǎn),不代表電子星球立場。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請聯(lián)系:editor@netbroad.com
本篇所含全部資料,點(diǎn)擊此處留下郵箱我會發(fā)給你
資料明細(xì):新建文本文檔.txt
覺得內(nèi)容不錯的朋友,別忘了一鍵三連哦!
贊 2
收藏 4
關(guān)注 181
成為作者 賺取收益
全部留言
0/200
  • dy-2nlUAZt9 02-18 00:02
    老師,能不能發(fā)我一下資料,謝謝! 46****@****.com
    回復(fù) 1條回復(fù)
主站蜘蛛池模板: 玩麻豆国产?片对白日逼视频 | 中文有码vs无码人妻 | 日本一区二区国产 | 亚洲精品乱码久久久久久不卡 | 九九久久精品一区 | 久久AV老司机精品网站导航 | 日本精品一区二区三区四区 | 四虎影视在线影院在线观看 | 惊爆摩天楼在线观看 | 在线看毛片的网站 | 欧美xxxx做受欧美88 | 亚洲色成人WWW永久网站 | 91精品国产自产在线观看自播 | 小黄文纯肉污到你湿 | 99re视频在线免费观看 | 在线免费av网站 | 麻豆免费观看 | 欧美专区日韩 | 久久人人玩人妻潮喷内射人人 | 天天爱天天操天天干 | 无码天堂亚洲国产AV麻豆 | 欧美精品无码一区二区三区 | 伊人久久大香线蕉av最新 | 女人久久久 | 天天躁日日躁狠狠躁性色avq | xxxxx黄色片| 欧美国产日韩在线 | 嘿咻嘿咻免费区在线观看 | 精品国产不卡一区二区三区 | 久久精品国产只有精品66 | 91九色丨porny丨交换 | 国产精品一区二区久久精品爱微奶 | 亚洲色欲色欲综合网站 | youjizz丰满熟妇中国 | 久久精品成人一区二区三区 | 二区三区偷拍浴室洗澡视频 | 欧美人免费视频网站在线 | 国产色噜噜噜91在线精品 | 8天堂资源在线 | 国产亚洲日韩A欧美在线人成 | 狂猛欧美激情性xxxx在线观看 |