1. 程式人生 > >【iniparser】C語言配置檔案解析庫 — iniparser 的使用

【iniparser】C語言配置檔案解析庫 — iniparser 的使用

O、簡介

C語言配置檔案解析庫 — iniparser可以方便的對配置檔案進行解析、新增、修改、刪除等操作。

配置檔案格式:

  • 註釋:iniparser會無視註釋,註釋以英文分號開頭(;這是配置檔案註釋)
  • 註釋結構:配置檔案包含兩個基本單元 section 和 key。其中 section 相當於一組 key 的名字,section下面包含 0或多個key,每個 key 是配置檔案的最小單元。
;section註釋
[setion1]
key11 = value11 
key12 = value12 

[setion2]
key21 = value21 
key22 = value22
...

注意: iniparser 的一條原則是 section 和 key 大小寫無關,寫入的字串全部小寫化,取出的字串也全部小寫化。

一、API

int iniparser_getnsec(dictionary * d);  //獲取dictionary物件的section個數
 
char * iniparser_getsecname(dictionary * d, int n); //獲取dictionary物件的第n個section的名字
 
void iniparser_dump_ini(dictionary * d, FILE * f);  //儲存dictionary物件到file
 
void iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f); //儲存dictionary物件一個section到file
 
void iniparser_dump(dictionary * d, FILE * f);  //列印整個配置檔案資訊(f賦值為stdout則輸出到終端)
 
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);   //返回dictionary物件的section:key對應的字串值
 
int iniparser_getint(dictionary * d, const char * key, int notfound);   //返回idictionary物件的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物件中是否存在某個section:key
 
dictionary * iniparser_load(const char * ininame);  //解析dictionary物件並返回(分配記憶體)dictionary物件
 
void iniparser_freedict(dictionary * d);    //釋放dictionary物件(記憶體)
 
unsigned dictionary_hash(const char * key); //計算關鍵詞的hash值
 
dictionary * dictionary_new(int size);  //建立dictionary物件
 
void dictionary_del(dictionary * vd);   //刪除dictionary物件
 
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物件的key值
 
void dictionary_dump(dictionary * d, FILE * out);   //儲存dictionary物件

二、使用

1、準備

- 下載原始碼,提取 src 中 4個原始檔(dictionary.h、dictionary.c、iniparser.h、iniparser.c),測試中新增到新建的 iniparser 目錄中;
- 由於 iniparser 是 dictionary 的再次封裝,使用時引用 iniparser.h 即可;
- 建立配置測試檔案(test_parser.ini);
;test_parser.ini

[it]
macbook                        = apple
xiaomi                         = MI

[browser]
chrome                         = google
firefox                        = mozilla
ie                             = microsoft

[server]
ip                             = 127.0.0.1
port                           = 10010

[testUpper]
upper                          = Upper

2、解析、取值、修改、刪除等基本操作

// name: ini_parser.c
// date: 2018-08-02

#include <stdio.h>
#include <stdlib.h>

#include "iniparser/iniparser.h"

void main(){

	dictionary *dict = NULL;

	printf("---------------------------------load-------------------------------\r\n");
	dict = iniparser_load("./test_parser.ini");
	if(NULL == dict){
		printf("iniparser load ini file failed, please check it...\r\n");
		exit(0);
	}

	iniparser_dump(dict, stdout);

	printf("---------------------------------read-------------------------------\r\n");
	printf("it_macbook: %s\r\n", iniparser_getstring(dict, "it:macbook", ""));

	printf("server_port: %d\r\n", iniparser_getint(dict, "server:port", 0));

	printf("---------------------------------find-------------------------------\r\n");
	if(iniparser_find_entry(dict, "server:ip")){
		printf("find entry server:ip, the value is: %s\r\n", iniparser_getstring(dict, "server:ip", ""));
	}else{
		printf("the entry server:ip not exist...\r\n");
    }
    
	if(iniparser_find_entry(dict, "it:golang")){
		printf("find entry it:golang, the value is: %s\r\n", iniparser_getstring(dict, "it:golang", ""));
	}else{
		printf("the entry it:golang not exist...\r\n");
	}
	
	printf("---------------------------------set-------------------------------\r\n");
	if(!iniparser_set(dict, "it:golang", "google")){
		printf("set it:golang entry OK.\r\n");
	}else{
		printf("set it:golang entry failed.\r\n");
    }
    
	if(iniparser_find_entry(dict, "it:golang")){
		printf("find entry it:golang, the value is: %s\r\n", iniparser_getstring(dict, "it:golang", ""));
    }else{
		printf("the entry it:golang not exist...\r\n");
    }

	printf("---------------------------------unset-------------------------------\r\n");
	iniparser_unset(dict, "it:golang");
	
	if(iniparser_find_entry(dict, "it:golang")){
		printf("find entry it:golang, the value is: %s\r\n", iniparser_getstring(dict, "it:golang", ""));
	}else{
		printf("the entry it:golang not exist...\r\n");
    }
    
	printf("---------------------------------dump ini-------------------------------\r\n");
	if(!iniparser_set(dict, "it:golang", "google")){
		printf("set it:golang entry OK.\r\n");
	}else{
		printf("set it:golang entry failed.\r\n");
	}
	
	FILE *ini_file = fopen("./test_parser.ini", "w");
	iniparser_dump_ini(dict, ini_file);
	fclose(ini_file);

	iniparser_dump(dict, stdout);

	iniparser_freedict(dict);
	
	printf("---------------------------------END-------------------------------\r\n");
}

// 編譯

$ gcc ini_parser.c iniparser/*.c 
// 結果

$ ./a.out
---------------------------------load-------------------------------
[it]=UNDEF
[it:macbook]=[apple]
[it:xiaomi]=[MI]
[browser]=UNDEF
[browser:chrome]=[google]
[browser:firefox]=[mozilla]
[browser:ie]=[microsoft]
[server]=UNDEF
[server:ip]=[127.0.0.1]
[server:port]=[10010]
[testupper]=UNDEF
[testupper:upper]=[Upper]
---------------------------------read-------------------------------
it_macbook: apple
server_port: 10010
---------------------------------find-------------------------------
find entry server:ip, the value is: 127.0.0.1
the entry it:golang not exist...
---------------------------------set-------------------------------
set it:golang entry OK.
find entry it:golang, the value is: google
---------------------------------unset-------------------------------
the entry it:golang not exist...
---------------------------------dump ini-------------------------------
set it:golang entry OK.
[it]=UNDEF
[it:macbook]=[apple]
[it:xiaomi]=[MI]
[browser]=UNDEF
[browser:chrome]=[google]
[browser:firefox]=[mozilla]
[browser:ie]=[microsoft]
[server]=UNDEF
[server:ip]=[127.0.0.1]
[server:port]=[10010]
[testupper]=UNDEF
[testupper:upper]=[Upper]
[it:golang]=[google]
---------------------------------END-------------------------------

3、遍歷、查詢

// name: ini_iter.c
// date: 2018-08-02

#include <stdio.h>
#include <stdlib.h>

#include "iniparser/iniparser.h"

void main(){

	int num = 0;
	char str[32] = {0};
	dictionary *dict = NULL;

	printf("---------------------------------load-------------------------------\r\n");
	dict = iniparser_load("./test_parser.ini");
	if(NULL == dict){
		printf("iniparser load ini file failed, please check it...\r\n");
		exit(0);
	}

	iniparser_dump(dict, stdout);

	printf("---------------------------------iter-------------------------------\r\n");
	num = iniparser_getnsec(dict);
	if(-1 == num){
		printf("iniparser getnsec failed...\r\n");
	}else{
		printf("section num: %d\r\n", num);
    }
    
	sprintf(str, "%s", iniparser_getsecname(dict, num-1));
	printf("the %d section name: %s\r\n", num, str);
	
	// 注意:儘量不要在ini中使用大寫命名,設定或者取出的字串全部小寫化處理,不能繼續使用大寫做比較
	if(!strcmp(str, "testupper")){
		printf("compare with testupper.\r\n");
	}
	
	if(!strcmp(str, "testUpper")){
		printf("compare with testUpper.\r\n");
    }
    
	num = iniparser_getsecnkeys(dict, str);
	printf("num: %d\r\n", num);

	const char *keys[32];
	iniparser_getseckeys(dict, str, keys);
	printf("key: %s\r\n", keys[0]);
	printf("value: %s\r\n", iniparser_getstring(dict, keys[0], ""));

	char tmp_str[32] = {0};
	sprintf(tmp_str, "%s:%s", "server", "ip");
	printf("value: %s\r\n", iniparser_getstring(dict, tmp_str, ""));
	
	iniparser_freedict(dict);
	
	printf("---------------------------------END-------------------------------\r\n");
}
// 編譯

$ gcc ini_iter.c iniparser/*.c
// 結果

$ ./a.out 
---------------------------------load-------------------------------
[it]=UNDEF
[it:macbook]=[apple]
[it:xiaomi]=[MI]
[it:golang]=[google]
[browser]=UNDEF
[browser:chrome]=[google]
[browser:firefox]=[mozilla]
[browser:ie]=[microsoft]
[server]=UNDEF
[server:ip]=[127.0.0.1]
[server:port]=[10010]
[testupper]=UNDEF
[testupper:upper]=[Upper]
---------------------------------iter-------------------------------
section num: 4
the 4 section name: testupper
compare with testupper.
num: 1
key: testupper:upper
value: Upper
value: 127.0.0.1
---------------------------------END-------------------------------

由於 iniparser 介面是 dictionary 的封裝,以上已經基本涵蓋所有介面用法。

三、 一些問題

**—— 2018-08-02 —— **