原地址:https://blog.csdn.net/niha1993825jian/article/details/41086403
#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 Line = %d Func=%s Date=%s Time=%s ", __FILE__, __LINE__, __FUNCTION__, __DATE__, __TIME__); #define PRINT_ERRMSG(STR) fprintf(stderr,"line:%d,msg:%s,eMsg:%s ", __LINE__, STR, strerror(errno)) 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 == strlen(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->option = NULL; /* 初始的option要为空 */ ps->next = cnf->data; /* cnf->data可能为NULL */ cnf->data = p = ps; /* 头插法插入链表 */ } Option *q = p->option; while (NULL != q && 0 != strcmp(q->key, key)) { q = q->next; /* 遍历option,检查key是否已经存在 */ } if (NULL == q) { /* 不存在option,则新建一个 */ q = (Option*)malloc(sizeof(Option)); if (NULL == q) { exit(-1); /* 申请内存错误 */ } strcpy(q->key, key); q->next = p->option; /*这里p->option可能为NULL,不过也没关系 */ p->option = q; /* 头插法插入链表 */ } strcpy(q->value, value); /* 无论如何要把值改了 */ return true; } /** * 去掉字符串内所有空白 * 且忽略注释部分 * 最终得到没有空白的字符串 **/ bool strip_comments(char *string, char comment) { if (NULL == string || ' ' == *string || ' ' == *string) { return false; /* 第一个字符为回车或换行,表示空行 */ } char *p, *q; /* 下面去掉字符串中所有空白字符 */ for (p = q = string; *p != '