C語(yǔ)言開(kāi)源庫(kù)iniparser解析ini文件的方法
1 ini文件介紹
- INI(Initialization File)文件是一種簡(jiǎn)單直觀的數(shù)據(jù)存儲(chǔ)格式,常用于配置應(yīng)用程序的初始化設(shè)置。這種文件通常包含若干個(gè)節(jié)(section)和鍵值對(duì)(key-value pairs)。INI文件的每一部分都是自描述性的,易于閱讀和編輯,使得非程序員也能輕易理解并修改配置參數(shù)。
- INI文件因其簡(jiǎn)單易用性而在許多編程語(yǔ)言中廣泛應(yīng)用,尤其是在Windows操作系統(tǒng)中,很多應(yīng)用程序都采用INI文件作為配置文件。當(dāng)然,隨著XML、JSON等更豐富、更結(jié)構(gòu)化的數(shù)據(jù)交換格式的普及,INI文件在現(xiàn)代應(yīng)用程序中的使用相對(duì)減少,但在一些輕量級(jí)應(yīng)用或?qū)?dòng)速度有較高要求的情況下,仍然是一種常見(jiàn)且實(shí)用的配置文件格式。
2 ini文件結(jié)構(gòu)
- 節(jié)(Section):INI文件中的各個(gè)部分通過(guò)方括號(hào) [] 包裹的名稱來(lái)定義,例如 [Section1]。每個(gè)節(jié)可以包含多個(gè)鍵值對(duì)。
- 鍵值對(duì)(Key-Value Pairs):鍵和值之間用等號(hào) = 分隔,如 key1=value1。鍵通常是描述性質(zhì)的字符串,而值則可以是字符串、數(shù)字或其他類型的數(shù)據(jù)。
- 注釋:注釋行以分號(hào) ; 開(kāi)始,直到行尾都被視為注釋內(nèi)容,不會(huì)被程序解析。
- 多行值:某些INI解析器允許值跨越多行,通常通過(guò)在行尾添加反斜杠 \ 來(lái)延續(xù)到下一行
iniparser
iniparser 是一個(gè)開(kāi)源的 C 語(yǔ)言庫(kù),用于解析和操作 INI 格式的配置文件
使用 iniparser 庫(kù)的應(yīng)用程序可以很方便地讀取和解析INI文件中的配置信息,大大簡(jiǎn)化了對(duì)配置文件的處理工作,降低了程序的開(kāi)發(fā)復(fù)雜度。由于其開(kāi)源屬性,開(kāi)發(fā)者可以根據(jù)自己的需求自由使用、研究和改進(jìn)該庫(kù)。
3 相關(guān)API
3.1 加載ini文件
/* * @brief 從ini格式的配置文件中加載數(shù)據(jù) * @param [IN] ininame 要打開(kāi)的ini格式文件 * @return != NULL 返回一個(gè)指向dictionary結(jié)構(gòu)的指針 * == NULL 加載ini文件失敗 */ dictionary * iniparser_load(const char *ininame);
3.2 獲取鍵值
/* * @brief 獲取指定鍵(key)對(duì)應(yīng)的字符串類型的值 * @param [IN] d dictionary結(jié)構(gòu)的指針 * @param [IN] key 要查找的鍵,通常格式為 "section:key",表示要獲取哪個(gè)節(jié)(section)下的哪一項(xiàng)(key)的值。 * @param [IN] def 當(dāng)鍵不存在或者其值不是字符串時(shí)的默認(rèn)返回值。如果沒(méi)有找到對(duì)應(yīng)鍵,函數(shù)將返回此默認(rèn)值。 * @return 如果找到了相應(yīng)的鍵,返回鍵值對(duì)應(yīng)字符串 * 如果沒(méi)有找到匹配的鍵,返回def指定的字符串值 */ const char * iniparser_getstring(const dictionary *d, const char *key, const char *def); /* * @brief 獲取指定鍵(key)對(duì)應(yīng)的整數(shù)值 * @param [IN] d dictionary結(jié)構(gòu)的指針 * @param [IN] key 要查找的鍵,通常格式為 "section:key",表示要獲取哪個(gè)節(jié)(section)下的哪一項(xiàng)(key)的值。 * @param [IN] notfound 當(dāng)鍵不存在或者其值不能被轉(zhuǎn)換為整數(shù)時(shí),函數(shù)將返回這個(gè)默認(rèn)值。 * @return 如果找到了相應(yīng)的鍵,并且其值可以被成功轉(zhuǎn)換為整數(shù),則返回該整數(shù)值。 * 如果沒(méi)有找到匹配的鍵,或者該鍵對(duì)應(yīng)的值無(wú)法轉(zhuǎn)換為整數(shù),則返回 notfound 參數(shù)提供的默認(rèn)值。 */ int iniparser_getint(const dictionary * d, const char * key, int notfound); /* * @brief 獲取指定鍵(key)對(duì)應(yīng)的浮點(diǎn)型值 * @param [IN] d dictionary結(jié)構(gòu)的指針 * @param [IN] key 要查找的鍵,通常格式為 "section:key",表示要獲取哪個(gè)節(jié)(section)下的哪一項(xiàng)(key)的值。 * @param [IN] notfound 當(dāng)鍵不存在或者其值無(wú)法轉(zhuǎn)換為雙精度浮點(diǎn)數(shù)時(shí),函數(shù)返回的默認(rèn)值。 * @return 如果找到了相應(yīng)的鍵,并且其值能成功轉(zhuǎn)換為一個(gè)雙精度浮點(diǎn)數(shù),則返回該浮點(diǎn)數(shù)。 * 如果沒(méi)有找到匹配的鍵,或者鍵的值不能被解釋為一個(gè)有效的雙精度浮點(diǎn)數(shù),則返回 notfound 參數(shù)所提供的默認(rèn)值。 */ double iniparser_getdouble(const dictionary *d, const char *key, double notfound);
3.3 設(shè)置鍵值
/* * @brief 設(shè)置或修改 ini 配置文件中某個(gè)鍵值對(duì) * @param [IN] d dictionary結(jié)構(gòu)的指針 * @param [IN] entry 字符串形式的鍵值對(duì)標(biāo)識(shí)符,格式通常是 "section:key",表明您要在哪個(gè)節(jié)(section)下的哪個(gè)鍵(key)上設(shè)置或修改值(val)。 * key值存在則修改對(duì)應(yīng)val,key值不存在則會(huì)新增 * @param [IN] val: 要設(shè)置的新值,作為字符串傳遞。 * @return 返回0表示設(shè)置成功 */ int iniparser_set(dictionary *ini, const char *entry, const char *val);
3.4 移除鍵值
/* * @brief 移除 ini 配置文件中某個(gè)鍵值對(duì) * @param [IN] d dictionary結(jié)構(gòu)的指針 * @param [IN] entry 字符串形式的鍵名,包括可選的部分名稱(section)和鍵(key) * 如果不指定key,則會(huì)移除整個(gè)section */ void iniparser_unset(ini, const char *entry);
3.5 判斷鍵是否存在
/* * @brief 判斷 ini 配置文件是否存在某個(gè)鍵值 * @param [IN] d dictionary結(jié)構(gòu)的指針 * @param [IN] entry 字符串形式的鍵值對(duì)標(biāo)識(shí)符,格式通常是 "section:key" * @return 返回1表示存在,返回0表示不存在 */ int iniparser_find_entry(const dictionary *ini, const char *entry);
3.6 獲取section個(gè)數(shù)
/* * @brief 獲取ini配置文件中section的數(shù)量 * @param [IN] d dictionary結(jié)構(gòu)的指針 * @return 成功返回section個(gè)數(shù),失敗返回 -1 */ int iniparser_getnsec(const dictionary * d); /* * @brief 獲取某個(gè)section值 * @param [IN] d dictionary結(jié)構(gòu)的指針 * @param [IN] n 指定獲取第幾個(gè)section值 * @return 成功返回獲取到的section值,失敗返回NULL */ const char *iniparser_getsecname(const dictionary * d, int n);
3.7 獲取section下key個(gè)數(shù)
/* * @brief 獲取ini配置文件中某個(gè)section的key個(gè)數(shù) * @param [IN] d dictionary結(jié)構(gòu)的指針 * @param [IN] s section * @return 返回指定section下的key個(gè)數(shù) */ int iniparser_getsecnkeys(dictionary * d, char * s); /* * @brief 獲取ini配置文件中某個(gè)section的所有key * @param [IN] d dictionary結(jié)構(gòu)的指針 * @param [IN] s section * @param [OUT] keys 通過(guò)這個(gè)參數(shù)輸出key,也可以通過(guò)返回值獲取 * @return 成功返回指定section下的key,失敗返回NULL */ const char **iniparser_getseckeys(const dictionary *d, const char *s, const char **keys)
3.8 保存dictionary對(duì)象到文件中
/* * @brief 保存dictionary對(duì)象到文件中 * @param [IN] d dictionary結(jié)構(gòu)的指針 * @param [IN] f 已打開(kāi)的文件描述符 */ void iniparser_dump_ini(const dictionary *d, FILE *f);
3.9 釋放dictionary對(duì)象
/* * @brief 釋放dictionary對(duì)象 * @param [IN] d dictionary結(jié)構(gòu)的指針 */ void iniparser_freedict(dictionary * d);
4 演示
4.1 獲取鍵值
ini文件內(nèi)容
[head] accecpt = */* length = 100 host = 192.168.1.2 port = 8087 rate = 9.98 [body] accept = XML data = json length = 200
測(cè)試代碼
#include <stdio.h>
#include <iniparser.h>
int main(){
// 加載配置
dictionary* ini = iniparser_load("config.ini");
if(ini == NULL){
return -1;
}
// 獲取鍵值
const char* cHeadHost = iniparser_getstring(ini, "head:host", "127.0.0.1");
printf("cHeadHost %s\n", cHeadHost);
const char* cBodyData = iniparser_getstring(ini, "body:data", "welcome");
printf("cBodyData %s\n", cBodyData);
int iHeadPort = iniparser_getint(ini, "head:port", 80);
printf("iHeadPort %d\n", iHeadPort);
double iHeadReate = iniparser_getdouble(ini, "head:rate", 9.99);
printf("iHeadReate %.2lf\n", iHeadReate);
// 釋放dictionary對(duì)象
iniparser_freedict(ini);
return 0;
}打印結(jié)果

4.2 設(shè)置鍵值
ini文件內(nèi)容
[head] accecpt = */* length = 100 host = 192.168.1.2 port = 8087 rate = 9.98 [body] accept = XML data = json length = 200
測(cè)試代碼
#include <stdio.h>
#include <iniparser.h>
int main(){
// 加載配置
dictionary* ini = iniparser_load("config.ini");
if(ini == NULL){
return -1;
}
// 有對(duì)應(yīng)鍵值則修改
int ret = iniparser_set(ini, "body:data", "iniparser");
if (ret != 0){
printf("iniparser_set body:data failed.\n");
}
// 沒(méi)有對(duì)應(yīng)鍵值則添加
ret = iniparser_set(ini, "body:msg", "success");
if (ret != 0){
printf("iniparser_set body:data failed.\n");
}
// 設(shè)置值成功后要進(jìn)行保存
FILE* fp = fopen("config.ini", "w");
if( fp == NULL ) {
printf("open ini file failed.\n");
return -1;
}
// 保存dictionary對(duì)象到file
iniparser_dump_ini(ini, fp);
fclose(fp);
// 釋放dictionary對(duì)象
iniparser_freedict(ini);
return 0;
}設(shè)置后新的ini文件內(nèi)容
[head] accecpt = */* length = 100 host = 192.168.1.2 port = 8087 rate = 9.98 [body] accept = XML data = iniparser length = 200 msg = success
4.3 遍歷section和鍵值
ini文件內(nèi)容
[head] accecpt = */* length = 100 host = 192.168.1.2 port = 8087 rate = 9.98 [body] accept = XML data = iniparser length = 200 msg = success
測(cè)試代碼
#include <stdio.h>
#include <iniparser.h>
int main(){
// 加載配置
dictionary* ini = iniparser_load("config.ini");
if(ini == NULL){
return -1;
}
// 遍歷section
int sectionNum = iniparser_getnsec(ini);
if(sectionNum != -1){
for(int i = 0; i < sectionNum; i++){
const char* cSection = iniparser_getsecname(ini, i);
if(cSection != 0){
printf("cSection : %s\n", cSection);
}
}
}
// 遍歷某個(gè)section下的key
int keyNum = iniparser_getsecnkeys(ini, "body");
//獲取dictionary對(duì)象某個(gè)section下所有的key
char keys[10][1024] = { 0 };
const char **p = (const char **)keys;
const char **retKeys = iniparser_getseckeys(ini, "body", p);
for (int i = 0; i < keyNum; i++){
printf("%s ", p[i]);
}
printf("\n");
// 釋放dictionary對(duì)象
iniparser_freedict(ini);
return 0;
}打印結(jié)果

到此這篇關(guān)于C語(yǔ)言開(kāi)源庫(kù)iniparser解析ini文件的文章就介紹到這了,更多相關(guān)C語(yǔ)言iniparser解析ini文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)停車場(chǎng)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)停車場(chǎng)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
利用C++實(shí)現(xiàn)簡(jiǎn)易的.ini配置文件解析器
這篇文章主要為大家詳細(xì)介紹了如何基于C++編寫(xiě)一個(gè)簡(jiǎn)易的.ini配置文件解析器,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以了解一下2023-03-03

