本文之前由于技术不到位,写的比较挫,最近花了大半天时间写了一个高级点的版本。
这里是我写的代码,已经上传到github了。跳转到github
主要是使用了链表保存ini文件的内容,在程序运行最初会初始化链表,接下来的查询操作都只是查询内存,比较快,而且此时也不依赖文件了。最大的改变就是自己对编程的熟悉和了解,再也不会写挫逼代码咯。
下面是源代码,个人感觉还不错。欢迎大家使用。
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_VALUE 64 /* 定义section,key,value字符串最大长度 */
// printf("File = %s\nLine = %d\nFunc=%s\nDate=%s\nTime=%s\n", __FILE__, __LINE__, __FUNCTION__, __DATE__, __TIME__);
#define PRINT_ERRMSG(STR) fprintf(stderr,"line:%d,msg:%s,eMsg:%s\n", __LINE__, STR, strerror(errno))
#define TRIM_LIFT 1 /* 去除左边空白字符 */
#define TRIM_RIGHT 2 /* 去除右边空白字符 */
#define TRIM_SPACE 3 /* 去除两边空白字符 */
typedef struct _option {
char key[MAX_VALUE]; /* 对应键 */
char value[MAX_VALUE]; /* 对应值 */
struct _option *next; /* 链表连接标识 */
}Option;
typedef struct _data {
char section[MAX_VALUE]; /* 保存section值 */
Option *option; /* option链表头 */
struct _data *next; /* 链表连接标识 */
}Data;
typedef struct {
char comment; /* 表示注释的符号 */
char separator; /* 表示分隔符 */
char re_string[MAX_VALUE]; /* 返回值字符串的值 */
int re_int; /* 返回int的值 */
bool re_bool; /* 返回bool的值 */
double re_double ; /* 返回double类型 */
Data *data; /* 保存数据的头 */
}Config;
/**
* 判断字符串是否为空
* 为空返回true,不为空返回false
**/
bool str_empty(const char *string)
{
return NULL == string || '\0' == *string;
}
/**
* 向链表添加section,key,value
* 如果添加时不存在section则新增一个
* 如果对应section的key不存在则新增一个
* 如果section已存在则不会重复创建
* 如果对应section的key已存在则只会覆盖key的值
**/
bool cnf_add_option(Config *cnf, const char *section, const char *key, const char *value)
{
if (NULL == cnf || str_empty(section) || str_empty(key) || str_empty(value)) {
return false; /* 参数不正确,返回false */
}
Data *p = cnf->data; /* 让变量p循环遍历data,找到对应section */
while (NULL != p && 0 != strcmp(p->section, section)) {
p = p->next;
}
if (NULL == p) { /* 说明没有找到section,需要加一个 */
Data *ps = (Data*)malloc(sizeof(Data));
if (NULL == ps) {
exit(-1); /* 申请内存错误 */
}
strcpy(ps->section, section);
ps->