ini是Windows上较常用的小型配置文件,并且windows api提供方便的函数供应用程序读写配置,可惜linux等其它操作系统上的需要用其它的方式.
我这儿写ini配置库是可以跨平台使用的,对于需要跨平台但使用相同配置的应用来说是个不错的选择.
支持符合windows ini标准的配置文件.
有趣兴的朋友可以拿去研究研究.
[2012-2-9日最新更新]
感谢前段时间一个网友提到程序的一些Bug,已修正程序,这次亲自在windows和linux下测试.已经支持GBK,UTF-8编码的ini文件解析。
/** * INI配置文件管理函数库 * Ini file parse functions. * By Hoverlees http://www.hoverlees.com me[at]hoverlees.com */ #ifndef _HOVERLEES_INI_CONFIG_H #define _HOVERLEES_INI_CONFIG_H #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> //#include <unistd.h> typedef struct _CONFIG_BTREE_NODE{ char* key; void* data; struct _CONFIG_BTREE_NODE* left; struct _CONFIG_BTREE_NODE* right; char mem[2]; }CONFIG_BTREE_NODE; typedef struct _CONFIG_BTREE{ int numNodes; CONFIG_BTREE_NODE* root; }CONFIG_BTREE; typedef CONFIG_BTREE INI_CONFIG; typedef int (*CONFIG_BTREE_TRAVERSE_CB)(CONFIG_BTREE_NODE* node); typedef int (*CONFIG_BTREE_SAVE_TRAVERSE_CB)(FILE* fp,CONFIG_BTREE_NODE* node); /** * ini内容解析函数,从字符串解析配置 * @param str 字符串 * @param slen 字符串长度,可以为0,如果为0,函数自动计算字符串长度 * @param isGBK 如果ini文件使用GBK字符集,设置成1,否则设置成0 * @return 成功返回INI_CONFIG指针,失败返回null */ INI_CONFIG* ini_config_create_from_string(unsigned char* str,int slen,int isGBK); /** * ini内容解析函数,从文件解析配置 * @param filename 配置文件名 * @param isGBK 如果ini文件使用GBK字符集,设置成1,否则设置成0 * @return 成功返回INI_CONFIG指针,失败返回null */ INI_CONFIG* ini_config_create_from_file(const char* filename,int isGBK); /** * 配置释放函数,释放所占用的内存及数据结构 * @param config 配置对象指针 * @return 成功返回1,失败返回0 */ void ini_config_destroy(INI_CONFIG* config); /** * 获取配置整数值 * @param config 配置对象指针 * @param section 段名,没有段名时可以为NULL * @param key 键名 * @param default_int 默认值 * @return 如果配置中有此键对应的值,返回该值,否则返回参数指定的默认值 */ int ini_config_get_int(INI_CONFIG* config,const char* section,const char* key,int default_int); /** * 获取配置字符串值 * @param config 配置对象指针 * @param section 段名,没有段名时可以为NULL * @param key 键名 * @param default_string 默认值 * @return 如果配置中有此键对应的值,返回该值,否则返回参数指定的默认值 */ char* ini_config_get_string(INI_CONFIG* config,const char* section,const char* key,char* default_string); /** * 设置变量 * @param config 配置对象指针 * @param section 段名,没有段名时可以为NULL * @param key 键名 * @param key_len 键长 * @param value 值 * @param value_len 值长度 * @return 成功为1,失败为0 */ int ini_config_set_string(INI_CONFIG* config,const char* section,const char* key,int key_len,const char* value,int value_len); /** * 设置变量 * @param config 配置对象指针 * @param section 段名,没有段名时可以为NULL * @param key 键名 * @param key_len 键长 * @param value 整数值 * @return 成功为1,失败为0 */ int ini_config_set_int(INI_CONFIG* config,const char* section,const char* key,int key_len,int value); /** * 保存配置到文件中 *提示,原先配置文件中的注释信息将不会保存. * @param config 配置对象指针 * @param filename 保存到的文件 * @return 成功为1,失败为0 */ int ini_config_save(INI_CONFIG* config,const char* filename); /** * 类似于ini_config_save,只是参数是文件指针,此函数可以直接使用stdin,stdout,stderr. *提示:本函数不负责关闭fp. * @param config 配置对象指针 * @param fp 文件指针 * @return 成功为1,失败为0 */ int ini_config_print(INI_CONFIG* config,FILE* fp); #endif
下面是调用示例:
#include "confile.h" void main(int argc,char* argv[]){ INI_CONFIG* config; printf("------------test1-----------\n"); config=ini_config_create_from_string("hover = lees \n data = 7 \n maxthread=255\n;this is a comment line\r\nyahoo =alibaba \n [section1] \nhover = lees2 \nhover=lees333\n\n hover = lees4444\nyahoo=3\n\n\n",0,0); if(config){ ini_config_print(config,stdout); ini_config_destroy(config); } printf("\n------------test2-----------\n"); config=ini_config_create_from_file("php.ini",0); if(config){ printf( "%s %s\n", ini_config_get_string(config,"soap","soap.wsdl_cache_dir","/nodir"), ini_config_get_string(config,"soap","soap.wsdl_cache_ttl","xixi") ); ini_config_destroy(config); } }
本例执行结果:
hover@hover-laptop:~/Desktop/c/inifile$ ./test ------------test1----------- [default] data=7 hover=lees maxthread=255 yahoo=alibaba [section1] hover=lees4444 yahoo=3 ------------test2----------- 2000 On
原代码在这里: 注意代码的编码是UTF-8的,因为本人在linux下开发的.如果要在windows下使用,请转换成GBK先.否则中文注释可能影响到代码.
confile.h confile.c
* INI配置文件管理函数库
* Ini file parse functions.
* By Hoverlees http://www.hoverlees.com me[at]hoverlees.com
*/
#ifndef _HOVERLEES_INI_CONFIG_H
#define _HOVERLEES_INI_CONFIG_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
//#include <unistd.h>
typedef struct _CONFIG_BTREE_NODE{
char* key;
void* data;
struct _CONFIG_BTREE_NODE* left;
struct _CONFIG_BTREE_NODE* right;
char mem[2];
}CONFIG_BTREE_NODE;
typedef struct _CONFIG_BTREE{
int numNodes;
CONFIG_BTREE_NODE* root;
}CONFIG_BTREE;
typedef CONFIG_BTREE INI_CONFIG;
typedef int (*CONFIG_BTREE_TRAVERSE_CB)(CONFIG_BTREE_NODE* node);
typedef int (*CONFIG_BTREE_SAVE_TRAVERSE_CB)(FILE* fp,CONFIG_BTREE_NODE* node);
/**
* ini内容解析函数,从字符串解析配置
* @param str 字符串
* @param slen 字符串长度,可以为0,如果为0,函数自动计算字符串长度
* @param isGBK 如果ini文件使用GBK字符集,设置成1,否则设置成0
* @return 成功返回INI_CONFIG指针,失败返回null
*/
INI_CONFIG* ini_config_create_from_string(unsigned char* str,int slen,int isGBK);
/**
* ini内容解析函数,从文件解析配置
* @param filename 配置文件名
* @param isGBK 如果ini文件使用GBK字符集,设置成1,否则设置成0
* @return 成功返回INI_CONFIG指针,失败返回null
*/
INI_CONFIG* ini_config_create_from_file(const char* filename,int isGBK);
/**
* 配置释放函数,释放所占用的内存及数据结构
* @param config 配置对象指针
* @return 成功返回1,失败返回0
*/
void ini_config_destroy(INI_CONFIG* config);
/**
* 获取配置整数值
* @param config 配置对象指针
* @param section 段名,没有段名时可以为NULL
* @param key 键名
* @param default_int 默认值
* @return 如果配置中有此键对应的值,返回该值,否则返回参数指定的默认值
*/
int ini_config_get_int(INI_CONFIG* config,const char* section,const char* key,int default_int);
/**
* 获取配置字符串值
* @param config 配置对象指针
* @param section 段名,没有段名时可以为NULL
* @param key 键名
* @param default_string 默认值
* @return 如果配置中有此键对应的值,返回该值,否则返回参数指定的默认值
*/
char* ini_config_get_string(INI_CONFIG* config,const char* section,const char* key,char* default_string);
/**
* 设置变量
* @param config 配置对象指针
* @param section 段名,没有段名时可以为NULL
* @param key 键名
* @param key_len 键长
* @param value 值
* @param value_len 值长度
* @return 成功为1,失败为0
*/
int ini_config_set_string(INI_CONFIG* config,const char* section,const char* key,int key_len,const char* value,int value_len);
/**
* 设置变量
* @param config 配置对象指针
* @param section 段名,没有段名时可以为NULL
* @param key 键名
* @param key_len 键长
* @param value 整数值
* @return 成功为1,失败为0
*/
int ini_config_set_int(INI_CONFIG* config,const char* section,const char* key,int key_len,int value);
/**
* 保存配置到文件中 *提示,原先配置文件中的注释信息将不会保存.
* @param config 配置对象指针
* @param filename 保存到的文件
* @return 成功为1,失败为0
*/
int ini_config_save(INI_CONFIG* config,const char* filename);
/**
* 类似于ini_config_save,只是参数是文件指针,此函数可以直接使用stdin,stdout,stderr. *提示:本函数不负责关闭fp.
* @param config 配置对象指针
* @param fp 文件指针
* @return 成功为1,失败为0
*/
int ini_config_print(INI_CONFIG* config,FILE* fp);
#endif
谢谢分享,已经用上了,避免了重复造轮子, = =
好文章,感谢分享
将ini配置文件抽象成BTree,我肯定是想不到的
看来我要学习要思考的东西还很多啊
嗨! 我测试了下你写的这个代发现 读文件的时候返回的总是默认的变量。而且ini文件中dedault字段一直会存在。
这份代码就可以直接在windows上编译。你也可以考虑直接用windows的ini的函数
请问有没有可以在windows系统下使用的头文件和源文件,能发我邮箱一份吗,有点急用,多谢!
亲,有警告,不够完美。。
你好,少量的你可以使用简单字符串搜索方法,如strstr,kmp,sunday等,大量的需要自己建立索引表,索引表的建立多种多样,这个关键就要看需求了。
请问下你有没有能够根据关键字,来存储和取出多行数据的相关代码或者方法,有的话能发我邮箱一份吗?多谢
ini文件的规范也是不能使用多行作为值吧,至少我写的这个不能这样。
你可以自己加escape,如\n表示换行,\\表示原始\
使用这些函数,发现一个问题,往配置文件里存东西的时候,可能有多行,但是读取的时候只能读出一行数据,其他的读不出来,这个问题怎么解决?谢谢
可否愿意把您的QQ之类的联系方式发我邮箱吗,方便交流,也交个朋友
呵呵,谢谢夸奖.
呵呵,期待您的修正哦,看到您的代码受益匪浅,学习了。
对对,我当时没有考虑到,我有空去修正这个问题。谢谢朋友的指出。
如果朋友急着要使用这个库,可以在我的跳转函数中判断当前字节是否大于127,如果大于,则再读一个字节,并将这两个字节当成一个字符来处理(GBK),如果第二个字节还是大于127,那么再读一个字节,并把这三个字节点一个字符处理(UTF-8),这样可以解决中文问题。
ini文件中,有中文,会coredump
Superior tinhknig demonstrated above. Thanks!