C实现配置文件(Ini文件)读取,跨平台
config.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #ifndef __CONFIG_H__ #define __CONFIG_H__ #include \"list.h\" typedef struct config_node { char *section; char *name; char *value; } config_node_t; int config_node_add(list_t *list, char *section, char *name, char *value); int config_load(list_t **list, const char *filepath); char *config_get(list_t *list, const char *section, const char *name, const char *def); void config_free(list_t *list); #endif /* __CONFIG_H__ */ |
config.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | #include #include #include #include #include #include #include #include \"config.h\" int config_node_add(list_t *list, char *section, char *name, char *value) { config_node_t *node = (config_node_t *)malloc(sizeof(config_node_t)); node->section = section; node->name = name; node->value = value; list_add(list, (void *)node); } int config_load(list_t **list, const char *filepath) { int fd, i,size; char *buf,*section,*name,*value, *p, *t, *s; struct stat fs; fd = open(filepath, O_RDONLY); if(fd < 0) { fprintf(stderr, \"open config file \'%s\' err.\\n\", filepath); return -1; } fstat(fd, &fs); size = fs.st_size + 1; buf = malloc(size); buf[size] = \'\\0\'; size = read(fd, buf, size); close(fd); list_init(list); p = buf; while(*p != \'\\0\') { while(*p != \'\\0\' && (*p == \' \' || *p == \'\\t\' || *p == \']\' || *p == \'\\r\' || *p == \'\\n\') ) p++; /* 注释 */ if(*p == \'#\') { p++; while(*p != \'\\0\' && *p != \'\\n\') p++; } /* 段 */ else if(*p == \'[\') { p++; while(*p != \'\\0\' && (*p == \' \' || *p == \'\\t\')) p++; t = p; while(*p != \'\\0\' && *p != \']\') p++; s = p; while(*s == \' \' || *s == \'\\t\' || *s == \'\\r\' || *s == \'\\n\') s--; size = s - t; section = malloc(size+1); section[size] = \'\\0\'; memcpy(section, t, size); config_node_add(*list, section, NULL, NULL); //debug //DEBUG(\"add section: \'%s\'\\n\", section); } /* 键值对 */ else if(*p != \'\\0\') { //if(section == NULL) continue; t = p; while(*p != \'\\0\' && *p != \'=\'&& *p != \'\\r\' && *p != \'\\n\') p++; s = p-1; while(*s == \' \' || *s == \'\\t\') s--; size = s - t + 1; name = malloc(size+1); name[size] = \'\\0\'; memcpy(name, t, size); p++; while(*p != \'\\0\' && (*p == \' \' || *p == \'\\r\' || *p == \'\\n\')) p++; t = p; while(*p != \'\\0\' && *p != \'=\'&& *p != \'\\r\' && *p != \'\\n\') p++; s = p - 1; while(*s == \'=\' || *s == \' \' || *s == \'\\t\') s--; size = s - t + 1; value = malloc(size+1); value[size] = \'\\0\'; memcpy(value, t, size); config_node_add(*list, section, name, value); //debug //DEBUG(\"add node: \'%s\' \'%s\' \'%s\'\\n\", section, name, value); } } free(buf); return 0; } char *config_get(list_t *list, const char *section, const char *name, const char *def) { int nlen = strlen(name); if(name == NULL) return NULL; list_node_t *p = list->first; while(p != NULL) { config_node_t *n = (config_node_t *)p->data; if((n->section == NULL && section != NULL) ||(section == NULL && n->section != NULL)) continue; if(n->section == section || strncmp(n->section, section,3) == 0) { if(n->name != NULL && strncmp(n->name, name, nlen) == 0) return n->value; } p = p->next; } return (char *)def; } void config_node_free(void *data) { config_node_t *node = (config_node_t *)data; if(node->name != NULL) free(node->name); if(node->value != NULL) free(node->value); if(node->name == NULL && node->value == NULL) free(node->section); } void config_free(list_t *list) { list_free(list, config_node_free); } |


great information you write it very clean. I am very lucky to get this tips from you.
Thanks for sharing this.
This is the 2nd occasion I have come across your blog post in the last couple weeks. Seems like I ought to take note of it.
i’m using oprea web-browser