ini文件读取

#ifndef INI_FILES_H_
#define INI_FILES_H_
#ifdef __cplusplus
extern "C" {
#endif
#define max_sec_len 20
#define max_key_len 20
#define max_val_len 64
#define max_section_counts 100

	struct ini_file;
	typedef struct ini_file* ini_file_handle;

	/**
	 *  函数:   load_ini_file
		*		创建一个ini文件句柄
	 *  参数: 
	 *          const char * const f_name ini文件全名,包括文件路径 
	 *  返回值:
	 *          NULL 创建ini文件句柄失败
	 *			非NULL 创建ini文件句柄成功
	 *  版本号:1.0
	 */
	ini_file_handle load_ini_file(const char*const f_name);
	/**
	 *  函数:   get_value          
	 *			获取对应的section,key值
	 *  参数: 
	 *          ini_file_handle h             ini文件句柄
	 *          const char * const s_name     section名称
	 *          const char * const k_name     key名称
	 * 
	 *  返回值:
	 *			NULL  没有找到对应的section,key值
	 *			非NULL 指向对应的section,key值
	 *  版本号:1.0
	 */
	const char*const get_value(ini_file_handle h, const char*const s_name,const char*const k_name);
	/**
	 *  函数:   get_section          
	 *			根据key,以及key对应的值返回包含第一个这个值得section名称
	 *  参数: 
	 *          ini_file_handle h           ini文件句柄
	 *          const char * const k_name   key名称
	 *          const char * const k_val    key对应的值
	 * 
	 *  返回值:
	 *          NULL    没有找到包含key=value的section
	 *			非NULL  指向第一个包含key=value的section名称
	 *  版本号:1.0
	 *
	 */const char*const get_section(ini_file_handle h,const char*const  k_name,const char*const k_val);
	/**
	 *  函数:   find_section          
	 *			查找该ini文件中是否包含一个特定的section
	 *  参数: 
	 *          ini_file_handle h          ini文件句柄
	 *          const char * const s_name  section名称 
	 *  返回值:
	 *          NULL   在该ini文件中没有找到指定的section
	 *			非NULL 指向ini文件中的section名称
	 *  版本号:1.0
	 *
	 */const char*const find_section(ini_file_handle h,const char*const s_name);
	/**
	 *  函数:   unload_ini_file          
	 *
	 *  参数: 
	 *          ini_file_handle h 
	 *  返回值:
	 *          void
	 *  版本号:1.0
	 *
	 */void unload_ini_file(ini_file_handle h);
#ifdef __cplusplus
}
#endif
#endif /* INI_FILES_H_ */


#include <ini_files.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#ifndef _countof
#define _countof(x) sizeof(x)/sizeof(x[0])
#endif
#define hints printf
#define max_line_count ((max_key_len + max_val_len) * 2)

#define common_checked(exp,ret) do{\
	if(exp)\
	{\
		hints("%s(%d)"#exp":error = %s(%d)\n",__FUNCTION__,__LINE__,strerror(errno),errno);\
		ret;\
	}\
}while(0)


struct key_values{
	char k_name[max_key_len];
	char v_valu[max_val_len];
};

struct section{
	struct key_values kv_sets[max_section_counts];
	int key_counts;
	char s_name[max_sec_len];
};

struct ini_file {
	struct section sections[max_section_counts];
	int sec_counts;
};




static int parse_ini_section(const char*const line,struct section*const sec){
	int ret = sscanf(line,"[%[^]]",sec->s_name);
	if(1 != ret){
		hints("parse section name failed = %s\n",line);
		return 0;
	}
	sec->key_counts = -1;
	return 1;
}

static int parse_ini_keyval(const char*const line,struct section*const sec){
	int j = ++(sec->key_counts);
	char*const k_name = sec->kv_sets[j].k_name;
	char*const k_valu = sec->kv_sets[j].v_valu;
	int ret = sscanf(line,"%[^=]=%s",k_name,k_valu);
	if (2 != ret){
		hints("parse key=value pare failed %s\n",line);
		return 0;
	}
	return 1;
}

static const char*const filter_ini_line(char*const line){
	char* commnet_pos = NULL;
	if (NULL == line){
		return line;
	}
	commnet_pos = strchr(line,';');
	if(NULL == commnet_pos){
		return line;
	}
	*commnet_pos = '\0';
	return (0 == strlen(line)) ? NULL : line;
}


static int parse_ini_context(FILE* f,struct section f_context[max_section_counts]){
	int i = 0;
	for (i = -1; !feof(f) && i < max_section_counts -1;) {
		char buffer[max_line_count] = {0};
		char*const line = fgets(buffer,sizeof(buffer),f);
		if (NULL == filter_ini_line(line)){
			continue;
		}
		if(NULL != strchr(line,'[') && NULL != strchr(line,']')){
			if(!parse_ini_section(line,&f_context[++i])){
				break;
			}
			continue;
		}
		if(NULL != strchr(line,'=')){
			if(!parse_ini_keyval(line,&f_context[i])){
				break;
			}
			continue;
		}
		hints("read error line %s\n",line);
	}
	return i;
}


static int load_ini_context(const char*const file_name, struct ini_file*const f_context) {
	FILE* file_handle = fopen(file_name, "r");
	common_checked(NULL == file_handle,return -1);
	memset(f_context,0,sizeof(struct ini_file));
	f_context->sec_counts = parse_ini_context(file_handle,f_context->sections);
	fclose(file_handle);
	return f_context->sec_counts;
}

ini_file_handle load_ini_file(const char*const f_name) {
	struct ini_file* ret = NULL;
	common_checked(NULL == f_name,return NULL);
	ret = (struct ini_file*)malloc(sizeof(struct ini_file));
	common_checked(NULL == ret , return NULL);
	if (load_ini_context(f_name,ret) <= 0){
		free(ret);
		return NULL;
	}
	return ret;
}

const char*const get_value(ini_file_handle h, const char*const s_name,const char*const k_name){
	int i = 0, j = 0;
	common_checked(NULL == s_name || NULL == k_name,return NULL);
	for (i = 0; i <= h->sec_counts; ++i) {
		if(0 == strcmp(s_name,h->sections[i].s_name)){
			break;
		}
	}
	if(i > h->sec_counts){
		hints("get section [%s] failed\n",s_name);
		return NULL;
	}
	for (j = 0; j <= h->sections[i].key_counts; ++j) {
		const struct key_values*const kv = &h->sections[i].kv_sets[j];
		if(0 == strcmp(k_name,kv->k_name)){
			return kv->v_valu;
		}
	}
	hints("get [%s] %s value failed\n",s_name,k_name);
	return NULL;
}

const char*const get_section(ini_file_handle h,const char*const k_name,const char*const k_val){
	int i = 0, j = 0;
	common_checked(NULL == k_name || NULL == k_val,return NULL);
	for (i = 0; i <= h->sec_counts; ++i) {
		for (j = 0; j <= h->sections[i].key_counts; ++j) {
			const char*const name = h->sections[i].kv_sets[j].k_name;
			const char*const valu = h->sections[i].kv_sets[j].v_valu;
			if( 0 == strcmp(k_name,name) && 0 == strcmp(k_val,valu)){
				return h->sections[i].s_name;
			}
		}
	}
	hints("get section failed by %s=%s\n",k_name,k_val);
	return NULL;
}

const char*const find_section(ini_file_handle h,const char*const s_name){
	int i = 0;
	common_checked(NULL == s_name,return NULL);
	for (i = 0; i <= h->sec_counts; ++i) {
		if(strcmp(h->sections[i].s_name,s_name) == 0){
			return h->sections[i].s_name;
		}
	}
	hints("find section failed %s\n",s_name);
	return NULL;
}

void unload_ini_file(ini_file_handle h){
	free(h);
}

#ifdef ini_file_test
#include <assert.h>
static void show_context(ini_file_handle h){
	int i= 0, j = 0;
	common_checked(NULL == h,return);
	for (i = 0; i <= h->sec_counts; ++i) {
		hints("[%s]\n",h->sections[i].s_name);
		for (j = 0; j <= h->sections[i].key_counts; ++j) {
			const struct key_values*const kv = &h->sections[i].kv_sets[j];
			hints("%s=%s\n",kv->k_name,kv->v_valu);
		}
	}
}

static void check_context(ini_file_handle h){
	int i = 0, j = 0;
	for (i = 0; i <= h->sec_counts; ++i){
		assert(NULL != find_section(h,h->sections[i].s_name));
		for (j = 0; j <= h->sections[i].key_counts;++j){
			assert(NULL != get_value(h,h->sections[i].s_name,h->sections[i].kv_sets[j].k_name));
			assert(NULL != get_section(h,h->sections[i].kv_sets[j].k_name,h->sections[i].kv_sets[j].v_valu));
		}
	}
	assert(NULL == get_section(h,"aa","bb"));
	assert(NULL == get_value(h,"aabb","bbaa"));
	assert(NULL == find_section(h,"acd"));
}
int main(int argc,char* argv[]){
	if(2 == argc){
		ini_file_handle fh = load_ini_file(argv[1]);
		common_checked(NULL == fh , return -1);
		show_context(fh);
		check_context(fh);
		unload_ini_file(fh);
		return 0;
	}
	printf("usage : %s file_name\n",argv[0]);
	return -1;
}
#endif





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值