<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      一文告訴你Linux下如何用C語言實現ini配置文件的解析和保存

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

      本文通過開源庫iniparser,詳細講解如何用C語言實現ini文件的參數解析和配置保存。

      本文代碼實例獲取方式見文末。

      一、ini文件

      1 什么是 ini文件

      • INI(Initialization File)文件是一種簡單直觀的數據存儲格式,常用于配置應用程序的初始化設置。這種文件通常包含若干個節(section)和鍵值對(key-value pairs)。INI文件的每一部分都是自描述性的,易于閱讀和編輯,使得非程序員也能輕易理解并修改配置參數。
      • INI文件因其簡單易用性而在許多編程語言中廣泛應用,尤其是在Windows操作系統中,很多應用程序都采用INI文件作為配置文件。當然,隨著XML、JSON等更豐富、更結構化的數據交換格式的普及,INI文件在現代應用程序中的使用相對減少,但在一些輕量級應用或對啟動速度有較高要求的情況下,仍然是一種常見且實用的配置文件格式。

      2 ini文件結構

      • 節(Section)

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

      • 鍵值對(Key-Value Pairs)

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

      • 注釋

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

      • 多行值

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

      3 ini文件舉例

      ;author yikoupeng
      
      [BASIC_INFO]
      version                = V1.1.1.1
      user                   = yikou
      number                 = 999
      
      
      [FTP]
      ftppath                = /home/ftp
      ftpuser                = ftp
      ftppass                = 123456
      port                   = 21
      
      ......
      

      其中:

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

      注意:

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

      二、 iniparser庫

      1. iniparser介紹

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

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

      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  
      

      3、進入目錄

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

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

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

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

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

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

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

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

      1 加載ini文件

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

      2 獲取鍵值

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

      3 設置鍵值

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

      4 移除鍵值

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

      5 判斷鍵是否存在

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

      6 獲取section個數

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

      7 獲取section下key個數

      • /*
        *  @brief  獲取ini配置文件中某個section的key個數
        *  @param  [IN]  d  dictionary結構的指針 
        *  @param  [IN]  s  section          
        *  @return 返回指定section下的key個數
        */
        int iniparser_getsecnkeys(dictionary * d, char * s); 
          
        /*
        *  @brief  獲取ini配置文件中某個section的所有key
        *  @param  [IN]  d  dictionary結構的指針 
        *  @param  [IN]  s  section      
        *  @param  [OUT]  keys  通過這個參數輸出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結構的指針   
        *  @param  [IN]  f  已打開的文件描述符
        */
        void iniparser_dump_ini(const dictionary *d, FILE *f);
        

      9 釋放dictionary對象

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

      10 api匯總

      • iniparser.h頭文件里面的API
      //獲取dictionary對象的section個數  
      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到file
      void iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f);  
      
       //保存dictionary對象到file 
      void iniparser_dump(dictionary * d, FILE * f);  
      
      //獲取dictionary對象某個section下的key個數 
      int iniparser_getsecnkeys(dictionary * d, char * s);  
      
      //獲取dictionary對象某個section下所有的key
      char ** iniparser_getseckeys(dictionary * d, char * s);   
      
      //返回dictionary對象的section:key對應的字串值  
      char * iniparser_getstring(dictionary * d, const char * key, char * def); 
      
       //返回idictionary對象的section:key對應的整形值  
      int iniparser_getint(dictionary * d, const char * key, int notfound); 
      
      //返回dictionary對象的section:key對應的雙浮點值  
      double iniparser_getdouble(dictionary * d, const char * key, double notfound);  
      
       //返回dictionary對象的section:key對應的布爾值  
      int iniparser_getboolean(dictionary * d, const char * key, int notfound);  
      
      //設置dictionary對象的某個section:key的值  
      int iniparser_set(dictionary * ini, const char * entry, const char * val); 
      
      //刪除dictionary對象中某個section:key
      void iniparser_unset(dictionary * ini, const char * entry);  
      
      //判斷dictionary對象中是否存在某個section:key
      int iniparser_find_entry(dictionary * ini, const char * entry) ;  
      
       //解析dictionary對象并返回(分配內存)dictionary對象
      dictionary * iniparser_load(const char * ininame);
      
      //釋放dictionary對象(內存)  
      void iniparser_freedict(dictionary * d);    
      
      • dictionary.h頭文件里面的API
       //計算關鍵詞的hash值
      unsigned dictionary_hash(const char * key); 
      
      //創建dictionary對象
      dictionary * dictionary_new(int size);   
      
      //刪除dictionary對象
      void dictionary_del(dictionary * vd);   
      
      //獲取dictionary對象的key值
      char * dictionary_get(dictionary * d, const char * key, char * def); 
      
      //設置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語言操作實例

      1、config.ini

      編寫配置文件:

      vim config.ini
      
      [BASIC_INFO]
      version                        = V1.1.1.1
      user                           = yikou
      number                         = 999
      
      
      [FTP]
      ftppath                        = /home/ftp
      ftpuser                        = ftp
      ftppass                        = 123456
      port                           = 21
      
      
      [NETWORK]
      interface                      = eth1
      dns1                           = 8.8.8.8
      dns2                           = 8.8.8.8
      subnet                         = 255.255.255.0
      router                         = 192.168.3.1
      

      2、讀取配置參數

      嘗試編寫iniparser程序對ini文件進行修改:

      #include <stdio.h>
      #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對象并返回(分配內存)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對應的字串值 */
          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;
      }
      
      

      可以看到最終值以配置文件中的為準。

      如果配置文件沒有配置參數則以iniparser_getxxxxx()中默認值為準。

      3、保存配置信息到文件

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

      int cfg_save_key(char *filename,char *section,char *key,char *value)
      參數:
          filename  配置文件名
          section   節名字
          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對象并返回(分配內存)dictionary對象*/
      	ini = iniparser_load(filename);
      	if( ini ==NULL)
      	{
      		printf("iniparser  failure\n");
      		return -1;
      	}
      
      	sprintf(item,"%s:%s",section,key);
      	
      	/* 設置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對象(內存)*/
      	iniparser_freedict(ini);
      
      }
      

      例如我們修改BASIC_INFO節的user的值為yikoupengnumber值為12345

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

      執行結果:

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

      后臺回復:iniparser

      posted @ 2025-01-20 21:37  一口Linux  閱讀(718)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产精品第二页在线播放| 亚洲国产欧美日韩另类| 欧美亚洲人成网站在线观看| 亚洲国产成人不卡高清麻豆| 无码抽搐高潮喷水流白浆| 国产gaysexchina男外卖| a级黑人大硬长爽猛出猛进| 国产一区二区日韩在线| 色欲综合久久中文字幕网| 强伦姧人妻免费无码电影| 国产一区二区三区尤物视频| 老太脱裤让老头玩ⅹxxxx| 日本在线 | 中文| 精品视频一区二区| 视频一区视频二区中文字幕| 欧美猛少妇色xxxxx猛叫| 国产精品美女www爽爽爽视频| 闵行区| 一区二区三区激情免费视频| 深夜视频国产在线观看| 国产美女自卫慰黄网站| 成年女人黄小视频| 国产亚洲精品在av| 激情五月日韩中文字幕| 久久午夜夜伦鲁鲁片免费无码| 国产一区二区三区自拍视频 | 中文字幕乱码中文乱码毛片| 亚洲国产成人精品无码一区二区 | 丰满爆乳一区二区三区| 国产成人综合在线女婷五月99播放| 福利网午夜视频一区二区| 亚洲男人的天堂久久香蕉| 国产精品麻豆成人av网| 梁河县| 中文字幕国产在线精品| 在线观看亚洲欧美日本| 国产精品成人aaaaa网站| 中文字幕日韩一区二区三区不卡| 国产v亚洲v天堂a无码| 女同在线观看亚洲国产精品| 在线中文一区字幕对白|