代码语言
.
CSharp
.
JS
Java
Asp.Net
C
MSSQL
PHP
Css
PLSQL
Python
Shell
EBS
ASP
Perl
ObjC
VB.Net
VBS
MYSQL
GO
Delphi
AS
DB2
Domino
Rails
ActionScript
Scala
代码分类
文件
系统
字符串
数据库
网络相关
图形/GUI
多媒体
算法
游戏
Jquery
Extjs
Android
HTML5
菜单
网页交互
WinForm
控件
企业应用
安全与加密
脚本/批处理
开放平台
其它
【
C
】
类似map的简单散列表,用于读取自定义的配置项
作者:
潜伏的胖子
/ 发布于
2013/3/18
/
617
用C写的一个类似map的简单散列表,用于读取自定义的配置项,可以实现大量配置项的快速访问。
/***************************************************** ********* 配置文件处理库 作者:Panlatent ********** *****************************************************/ #include <string.h> #include <unistd.h> #include <stdio.h> #include <stdarg.h> #include <stdlib.h> /*************************************************** ***************** 实现哈希表功能的函数集 ************** ***************************************************/ struct nodes { char *keystr; char *valstr; struct nodes *next; } ; struct nodelist{ unsigned short int keyc; unsigned short int valc; unsigned short int len; struct nodes **first; } ; typedef struct nodes * NODE; typedef struct nodelist * NELT; #define NODELIST_MAX_INIT 100 static struct nodes *infi_node_malloc(const char *keystr, const char *valstr) { struct nodes *node = malloc(sizeof(node)); if (node == NULL) return NULL; char *newkeystr = malloc(strlen(keystr) + 1); if (newkeystr == NULL) { free(node); return NULL; } char *newvalstr = malloc(strlen(valstr) + 1); if (newvalstr == NULL) { free(newkeystr); free(node); return NULL; } strcpy(newkeystr, keystr); strcpy(newvalstr, valstr); *(newkeystr + strlen(keystr)) = '\0'; *(newvalstr + strlen(valstr)) = '\0'; node->keystr = newkeystr; node->valstr = newvalstr; node->next = NULL; return node; } static void infi_node_free(struct nodes *node) { struct nodes *nextnode = node->next, *nownode; free(node->keystr); free(node->valstr); free(node); while (nextnode != NULL) { nownode = nextnode; free(nownode->keystr); free(nownode->valstr); free(nownode); nextnode = nextnode->next; } } static int infi_node_cmp(const struct nodes *node, const char *keystr) { if (strcmp( node->keystr, keystr) == 0) return 1; else return 0; } static unsigned int infi_hashkey(const char *keystr, const unsigned int hashlen) { unsigned long int i = 0; unsigned long long int hashmovalue[4] = {0,0,0,0}; while (*(keystr + i) != '\0') { unsigned short int tent = *(keystr + i)/10 == 0 ? 1 : 10; hashmovalue[i%4] = hashmovalue[i%4]*tent + (*(keystr + i) - 48); i += 1; } long long int hashkey = hashmovalue[0] + hashmovalue[1] + hashmovalue[2] + hashmovalue[3]; return hashkey%hashlen; } static int infi_hashd(int i) { int mul = 1, sign; sign = (i % 2)? -1: 1; mul = mul + i/2; return mul*sign; } static struct nodelist *infi_nodelist_init(int max) { if (max <= 0) max = NODELIST_MAX_INIT; struct nodelist *nelt = malloc(sizeof(struct nodelist)); if (nelt == NULL) return NULL; nelt->first = calloc(max, sizeof(struct nodes **)); if (nelt->first == NULL) { free(nelt); return NULL; } nelt->keyc = 0; nelt->valc = 0; nelt->len = max; return nelt; } static int infi_nodelist_exist(const struct nodelist *nelt, const unsigned int key) { if (*(nelt->first + key) == NULL) return 0; else return 1; } /*释放整个表*/ static void infi_nodelist_free(const struct nodelist *nelt) { if (nelt == NULL) return; int i; for (i = 0; i < nelt->len; i++) { if (*(nelt->first + i) == NULL) continue; else infi_node_free(*(nelt->first +i)); } } static char **infi_nodelist_getall(const struct nodelist *nelt) { if (nelt == NULL) return NULL; int i, times = 0; char **keyallstr = malloc(sizeof(char *) * nelt->valc); for (i = 0; i < nelt->len; i++) { if (*(nelt->first + i) == NULL) continue; else { *(keyallstr + times) = (*(nelt->first + i))->keystr; times += 1; } } return keyallstr; } /*关键字包含的参数数量查询*/ static int infi_nodelist_valc(const struct nodelist *nelt, const char *keystr) { unsigned int key, i = 0, errortimes = 0, num; key = infi_hashkey(keystr, nelt->len); struct nodes *nownelt = NULL; if (infi_nodelist_exist(nelt, key) == 1) { do { if (infi_node_cmp(*(nelt->first + key), keystr) == 1) { nownelt = *(nelt->first + key); num = 1; do { nownelt = nownelt->next; if (nownelt == NULL) { break; } num += 1; } while(nownelt->next != NULL); return num; } key = infi_hashkey(keystr, nelt->len) + infi_hashd(i); if (key < 0 || key >= nelt->len) { if(errortimes == 1) return 0; key = infi_hashkey(keystr, nelt->len); errortimes = 1; } else errortimes = 0; i += 1; } while(infi_nodelist_exist(nelt, key)); return 0; } else return 0; } /*添加属性*/ static int infi_nodelist_write(struct nodelist * const nelt, const char *keystr,const char *valstr) { unsigned int key, i = 0, errortimes = 0; key = infi_hashkey(keystr, nelt->len); struct nodes *nownelt = NULL; if (infi_nodelist_exist(nelt, key) == 1) { do { if (infi_node_cmp(*(nelt->first + key), keystr) == 1) { nownelt = *(nelt->first + key); while (nownelt->next != NULL) { nownelt = nownelt->next; } nownelt->next = infi_node_malloc(keystr, valstr); nelt->valc += 1; return 1; } key = infi_hashkey(keystr, nelt->len) + infi_hashd(i); if (key < 0 || key >= nelt->len) { if(errortimes == 1) return 0; key = infi_hashkey(keystr, nelt->len); errortimes = 1; } else errortimes = 0; i += 1; } while(infi_nodelist_exist(nelt, key)); nownelt = *(nelt->first + key); *(nelt->first + key) = infi_node_malloc(keystr, valstr); nelt->valc += 1; nelt->keyc += 1; return 1; } else { nownelt = *(nelt->first + key); *(nelt->first + key) = infi_node_malloc(keystr, valstr); nelt->valc += 1; nelt->keyc += 1; return 1; } } /*读取给定关键字的指定位置的值*/ static int infi_nodelist_read(const struct nodelist *nelt, const char *keystr, int num, char **valstr) { unsigned int key, i = 0, errortimes = 0; key = infi_hashkey(keystr, nelt->len); struct nodes *nownelt = NULL; if (infi_nodelist_exist(nelt, key) == 1) { do { if (infi_node_cmp(*(nelt->first + key), keystr) == 1) { nownelt = *(nelt->first + key); do { if (num == 0) { *valstr = nownelt->valstr; return 1; } nownelt = nownelt->next; num -= 1; if (nownelt->next == NULL) { if (num == 0) { *valstr = nownelt->valstr; return 1; } else return 0; } } while(nownelt->next != NULL); return 0; } key = infi_hashkey(keystr, nelt->len) + infi_hashd(i); if (key < 0 || key >= nelt->len) { if(errortimes == 1) return 0; key = infi_hashkey(keystr, nelt->len); errortimes = 1; } else errortimes = 0; i += 1; } while(infi_nodelist_exist(nelt, key)); return 0; } else return 0; } /*************************************************** *************** 键值对任务处理队列函数集 ************** ***************************************************/ struct queues{ char *keystr; char *valstr; struct queues *next; } ; struct queue{ struct queues *first; struct queues *tail; int length; char *keystr; char *valstr; } ; typedef struct queue * QUEU; static int infi_queue_get(struct queue * const queu); static struct queue *infi_queue_init() { struct queue *queu = malloc(sizeof(struct queue)); if (queu == NULL) return NULL; queu->first = NULL; queu->tail = NULL; queu->length = 0; queu->keystr = NULL; queu->valstr = NULL; return queu; } static void infi_queue_free(struct queue * const queu) { if (queu == NULL) return; if (queu->length == 0) free(queu); else { do { infi_queue_get(queu); free(queu->keystr); free(queu->valstr); } while (queu->length == 0); free(queu); } } static int infi_queue_set(struct queue *const queu, const char *keystr, const char *valstr) { if (queu == NULL) return 0; struct queues *newqueue = malloc(sizeof(struct queues)); if (newqueue == NULL) return 0; char *newkeystr = malloc(strlen(keystr) + 1); if (newkeystr == NULL) { free(newqueue); return 0; } char *newvalstr = malloc(strlen(valstr) + 1); if (newvalstr == NULL) { free(newkeystr); free(newqueue); return 0; } strcpy(newkeystr, keystr); strcpy(newvalstr, valstr); *(newkeystr + strlen(keystr)) = '\0'; *(newvalstr + strlen(valstr)) = '\0'; newqueue->keystr = newkeystr; newqueue->valstr = newvalstr; newqueue->next = NULL; if (queu->first == NULL) queu->first = newqueue; if (queu->tail == NULL) queu->tail = newqueue; else { queu->tail->next = newqueue; queu->tail = newqueue; } queu->length += 1; return 1; } static int infi_queue_get(struct queue * const queu) { if (queu == NULL) /*字符串空间由调用函数释放,或则由infi_queue_free一并释放*/ return 0; if (queu->length == 0) return 0; queu->keystr = queu->first->keystr; queu->valstr = queu->first->valstr; struct queues *next = queu->first->next; if ( next == NULL) queu->tail = NULL; free(queu->first); queu->first = next; queu->length -= 1; return 1; } /*************************************************** **************** 配置文件处理处理函数集 *************** ***************************************************/ typedef struct { FILE *file; NELT nelt; struct queue *queu; } infofile; #define BUFFER_KEYSTR_LEN 64 #define BUFFER_VALSTR_LEN BUFFER_KEYSTR_LEN*4 #define VARIABLE_NUM_MAX 32 static int grammar_analysis(const infofile *infi); static int variable(char * const variable_name); /*打开一个配置文件并进行基本初始化工作*/ extern infofile *infofile_open(const char *filename, int nodelistmax) { infofile *infi = malloc(sizeof(infofile)); if (infi == NULL) return NULL; infi->file = fopen(filename, "rb"); if (infi->file == NULL) { free(infi); return NULL; } infi->nelt = infi_nodelist_init(nodelistmax); if (infi->nelt == NULL) { free(infi); return NULL; } infi->queu = infi_queue_init(); if (infi->queu == NULL) { infi_nodelist_free(infi->nelt); free(infi); return NULL; } return infi; } /*对打开的配置文件进行词法分析,建立哈希表并存储相关分析后的内容*/ extern int infofile_analysis(infofile * const infi) { if (infi == NULL) return 0; if (infi->queu == NULL) { infi->queu = infi_queue_init(); if (infi->queu == NULL) return 0; } if (infi->nelt->valc != 0) { int nodelistmax = infi->nelt->len; infi_nodelist_free(infi->nelt); infi->nelt = infi_nodelist_init(nodelistmax); if (infi->nelt == NULL) return 0; } if (grammar_analysis(infi) == 0) return 0; while (infi->queu->length != 0) { infi_queue_get(infi->queu); infi_nodelist_write(infi->nelt, infi->queu->keystr,infi->queu->valstr); } infi_queue_free(infi->queu); infi->queu = NULL; return 1; } /*销毁哈希表并释放所有资源*/ extern void infofile_exit(infofile * const infi) { if (infi != NULL) { infi_queue_free(infi->queu); infi_nodelist_free(infi->nelt); fclose(infi->file); infi->queu = NULL; infi->nelt = NULL; infi->file = NULL; } } /*返回整个哈希表中所有键的值的总和*/ extern int infofile_valc(const infofile *infi) { if (infi == NULL) return 0; if (infi->nelt == NULL) return 0; return infi->nelt->valc; } /*返回关键字数量*/ extern int infofile_keyc(const infofile *infi) { if (infi == NULL) return 0; if (infi->nelt == NULL) return 0; return infi->nelt->keyc; } /*获取整个哈希表中的全部关键字*/ extern int infofile_getall(const infofile *infi, void **keystr) { static char *lastgetall = NULL; if (infofile_keyc(infi) == 0) { keystr = NULL; return 0; } if (lastgetall != NULL) { free(lastgetall); lastgetall = NULL; } *keystr = infi_nodelist_getall(infi->nelt); lastgetall = *keystr; return 1; } /*读取一个键中指定位置的值*/ extern int infoval_read(const infofile *infi, const char *keystr, int num, char **valstr) { if (infi == NULL) return 0; if (infi->nelt == NULL) return 0; if (infi_nodelist_read(infi->nelt, keystr, num, valstr) == 0) { return 0; } else return 1; } /*计算一个键中包含多少个值*/ extern int infoval_count(const infofile *infi, const char *keystr) { if (infi == NULL) return 0; if (infi->nelt == NULL) return 0; return infi_nodelist_valc(infi->nelt, keystr); } /*配置文件语法分析函数,分析后的文本段将加入处理队列*/ static int grammar_analysis(const infofile *infi) { if (infi == NULL) return 0; char *buffer_keystr = malloc(sizeof(char) * BUFFER_KEYSTR_LEN); if (buffer_keystr == NULL) return 0; char *buffer_valstr = malloc(sizeof(char) * BUFFER_VALSTR_LEN); if (buffer_valstr == NULL) { free(buffer_keystr); return 0; } unsigned int ikey = 0, ival = 0; /*无意义状态->注释状态->关键字状态->参数状态->参数终结状态*/ char notmean_state = 1, note_state = 0, key_state = 0, arg_state = 0, exit_state = 1; char nowchr = fgetc(infi->file); while (nowchr != EOF) { if (notmean_state == 1) { if (note_state == 0) { if (nowchr == '#') { note_state = 1; } else if((nowchr >= 65 && nowchr <=90) || (nowchr >= 97 && nowchr <= 122) || nowchr == '_' || (nowchr >= 48 && nowchr <= 57)) { notmean_state = 0; note_state = 0; key_state = 1; *(buffer_keystr + ikey) = nowchr; ikey += 1; } } else { if (nowchr == '\n') { note_state = 0; } } }用C写的一个类似map的简单散列表,用于读取自定义的配置项 else { if (note_state == 1) { if (nowchr == '\n') { note_state = 0; } } else { if (key_state == 1) { if((nowchr >= 65 && nowchr <=90) || (nowchr >= 97 && nowchr <= 122) || nowchr == '_' || (nowchr >= 48 && nowchr <= 57)) { *(buffer_keystr + ikey) = nowchr; ikey += 1; } else { switch (nowchr) { case ' ': case '\n': case '\t': key_state = 0; break; case '"': key_state = 0; arg_state = 1; break; case '#': key_state = 0; note_state = 1; break; default: key_state = 0; break; } *(buffer_keystr + ikey) = '\0'; } } else if (arg_state == 1) { char nextchr; unsigned int variable_num; char *variable_name = malloc(sizeof(char) * VARIABLE_NUM_MAX + 1); switch (nowchr) { case '\\': nextchr = fgetc(infi->file); switch (nextchr) { case 'n': *(buffer_valstr + ival) = '\n'; ival += 1; break; case 'r': *(buffer_valstr + ival) = '\r'; ival += 1; break; case 't': *(buffer_valstr + ival) = '\t'; ival += 1; break; case 'b': *(buffer_valstr + ival) = '\b'; ival += 1; break; case '"': *(buffer_valstr + ival) = '"'; ival += 1; break; case '\\': *(buffer_valstr + ival) = '\\'; ival += 1; break; case '$': *(buffer_valstr + ival) = '$'; ival += 1; break; default: *(buffer_valstr + ival) = nowchr; *(buffer_valstr + ival + 1) = nextchr; ival += 2; break; } case '\n': break; case '\t': *(buffer_valstr + ival) = '\t'; ival += 1; break; case '$': for (variable_num = 0; variable_num < VARIABLE_NUM_MAX; variable_num++) { nextchr = fgetc(infi->file); if (nextchr == '.') { *(variable_name + variable_num) = '\0'; if (variable(variable_name) == 1) { strcpy(buffer_valstr + ival, variable_name); ival += strlen(variable_name); } else { *(buffer_valstr + ival) = '$'; ival += 1; strcpy(buffer_valstr + ival, variable_name); ival += variable_num; *(buffer_valstr + ival) = '.'; ival += 1; } break; } else if((nextchr >= 65 && nextchr <=90) || (nextchr >= 97 && nextchr <= 122) || nextchr == '_' || (nextchr >= 48 && nextchr <= 57)) { *(variable_name + variable_num) = nextchr; continue; } *(buffer_valstr + ival) = '$'; ival += 1; strcpy(buffer_valstr + ival, variable_name); ival += variable_num; break; } if (variable_num == VARIABLE_NUM_MAX -1 && nextchr != '.') { *(buffer_valstr + ival) = '$'; ival += 1; strcpy(buffer_valstr + ival, variable_name); ival += variable_num; } break; case '"': *(buffer_valstr + ival) = '\0'; ival = 0; infi_queue_set(infi->queu, buffer_keystr, buffer_valstr); arg_state = 0; exit_state = 1; break; default: *(buffer_valstr + ival) = nowchr; ival += 1; break; } } else { if (exit_state == 1) { switch (nowchr) { case '#': arg_state = 0; note_state = 1; ikey = 0; notmean_state = 1; break; case '\n': note_state = 0; arg_state = 0; ikey = 0; notmean_state = 1; break; case ':': exit_state = 0; break; case '"': key_state = 0; arg_state = 1; break; default: break; } } else { switch (nowchr) { case '#': note_state = 1; break; case '"': key_state = 0; arg_state = 1; break; default: break; } } } } } nowchr = fgetc(infi->file); } free(buffer_keystr); free(buffer_valstr); return 1; } /*定义变量文本替换*/ static int variable(char * const variable_name) { static char path[256]; getcwd(path, 256); if (strcmp(variable_name, "PATH") == 0) { strcpy(variable_name, path); *(variable_name + strlen(variable_name)) = '\0'; return 1; } else return 0; }
试试其它关键字
简单散列表
同语言下
.
获取手机通讯录 iOS去除数字以外的所有字符
.
异步加载音乐等资源
.
交通罚单管理系统
.
freemark实现,简单的替换
.
计算斐波那契数列
.
base64解码 包括解码长度
.
图像显示
.
冒泡排序
.
输入十进制数,输出指定进制
.
链式栈
可能有用的
.
C#实现的html内容截取
.
List 切割成几份 工具类
.
SQL查询 多列合并成一行用逗号隔开
.
一行一行读取txt的内容
.
C#动态修改文件夹名称(FSO实现,不移动文件)
.
c# 移动文件或文件夹
.
c#图片添加水印
.
Java PDF转换成图片并输出给前台展示
.
网站后台修改图片尺寸代码
.
处理大图片在缩略图时的展示
潜伏的胖子
贡献的其它代码
(
1
)
.
类似map的简单散列表,用于读取自定义的配置项
Copyright © 2004 - 2024 dezai.cn. All Rights Reserved
站长博客
粤ICP备13059550号-3