纯C语言INI文件解析
生活随笔
收集整理的這篇文章主要介紹了
纯C语言INI文件解析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? ? 在一個跨平臺( Android 、Windows、Linux )項目中配置文件用 INI 格式,自己寫了個解析庫,純C語言的,簡單好用。
? ? 可以解析 INI 格式的字符串、解析文件、保存到文件。
? ? 下面是頭文件:
#ifndef INI_PARSER_H #define INI_PARSER_H #ifdef __cplusplus extern "C" { #endif struct tag_value_list;struct ini_parser {struct tag_value_list * keyvalues;int (*parse_file)(struct ini_parser *, const char * file);int (*parse_string)(struct ini_parser *, const char *text);char * (*value)(struct ini_parser *, const char * key);void (*set_value)(struct ini_parser *, const char * key, const char * value);void (*remove)(struct ini_parser *, const char *key);int (*save_to_file)(struct ini_parser *, const char * file); };struct ini_parser * new_ini_parser(); void delete_ini_parser(struct ini_parser *);#ifdef __cplusplus } #endif #endif // INI_PARSER_H? ? 下面是源文件:
#include "ini_parser.h" #include <stdio.h> #include <string.h> #include "tag_value.h"static struct tag_value_pair * parse_line(char *line, int len) {struct tag_value_pair * pair = 0;int count = 0;char * p = line;char * end = 0;char * start = line;if(!p) return 0;while(*p == ' ') p++;/*blank line*/if(p - line == len ||*p == '\r' ||*p == '\n' ||*p == '\0') return 0;/*do not support group*/if(*p == '[') return 0;/*comments*/if(*p == '#') return 0;/* extract key */start = p;end = line + len;while(*p != '=' && p!= end) p++;if(p == end){/* none '=' , invalid line */return 0;}end = p - 1;while(*end == ' ') end--; /* skip blank at the end */count = end - start + 1;pair = new_tag_value_pair();pair->szTag = malloc(count + 1);strncpy(pair->szTag, start, count);pair->szTag[count] = 0;/* extract value */p++;end = line + len; /* next pos of the last char */while( *p == ' ' && p != end) p++;if(p == end){delete_tag_value_pair(pair);return 0;}start = p;end--; /* to the last char */if(*end == '\n') { *end = 0; end--; }if(*end == '\r') { *end = 0; end--; }count = end - start + 1;if(count > 0){pair->szValue = malloc(count + 1);strncpy(pair->szValue, start, count);pair->szValue[count] = 0;}/* release empty key-value pair */if(!pair->szValue){delete_tag_value_pair(pair);return 0;}return pair; }static int _parse_file(struct ini_parser * ini, const char *file){FILE * fp = fopen(file, "r");if(fp){struct tag_value_pair * pair = 0;char buf[1024] = {0};while(fgets(buf, 1024, fp)){pair = parse_line(buf, strlen(buf));if(pair){ini->keyvalues->add(ini->keyvalues, pair);}}fclose(fp);return ini->keyvalues->size;}return -1; }static int _parse_text(struct ini_parser * ini, const char * text){char *p = text;char * start = 0;struct tag_value_pair * pair = 0;if(!text) return -1;while(1){start = p;while(*p != '\n' && *p != '\0' )p++;if(*p == '\0') break;pair = parse_line(start, p - start);if(pair) ini->keyvalues->add(ini->keyvalues, pair);p++;}return ini->keyvalues->size; }static char * _value(struct ini_parser * ini, const char * key){struct tag_value_pair * pair = ini->keyvalues->find_by_tag(ini->keyvalues, key);if(pair) return pair->szValue;return 0; }static void _set_value(struct ini_parser * ini, const char * key, const char *value){struct tag_value_pair * pair = ini->keyvalues->find_by_tag(ini->keyvalues, key);if(pair){if(pair->szValue) free(pair->szValue);pair->szValue = strdup(value);}else{ini->keyvalues->add(ini->keyvalues, make_tag_value_pair(key, value));} }static void _remove(struct ini_parser * ini, const char * key){struct tag_value_pair * pair = ini->keyvalues->find_by_tag(ini->keyvalues, key);if(pair)ini->keyvalues->remove(ini->keyvalues, pair); }static void write_keyvalue(struct tag_value_pair * pair, FILE *fp) {fputs(pair->szTag, fp);fputc('=', fp);fputs(pair->szValue, fp);fputc('\n', fp); }static int _save_to_file(struct ini_parser * ini, const char * file){if(ini->keyvalues->size > 0){FILE * fp = fopen(file, "w");if(fp){struct tag_value_pair * pair = ini->keyvalues->head;while(pair != ini->keyvalues->tail){write_keyvalue(pair, fp);pair = pair->next;}if(pair)write_keyvalue(pair, fp);fclose(fp);return 0;}}return -1; }struct ini_parser * new_ini_parser(){struct ini_parser * ini = (struct ini_parser*)malloc(sizeof(struct ini_parser));ini->keyvalues = new_tag_value_list();ini->parse_file = _parse_file;ini->parse_string = _parse_text;ini->value = _value;ini->set_value = _set_value;ini->remove = _remove;ini->save_to_file = _save_to_file;return ini; }void delete_ini_parser(struct ini_parser *ini){if(ini){delete_tag_value_list(ini->keyvalues);free(ini);} }? ? 測試代碼: #include "util/ini_parser.h" #include "ini_test.h" #include <stdio.h> #include <assert.h>static char * g_szIniString = "#abc\nfirst=2\nsecond\nname=charli zhang \n";static void ini_parser_test_string() {struct ini_parser * ini = new_ini_parser();int size = ini->parse_string(ini, g_szIniString);assert( size > 0);assert( ini->value(ini, "second") == 0 );assert( ini->value(ini, "abc") == 0);assert( ini->value(ini, "name") != NULL );assert( ini->value(ini, "first") != NULL);printf("ini string: %s\n", g_szIniString);printf("key-value pairs count = %d\n", size);printf("key \'name\'', value = %s\n", ini->value(ini, "name"));printf("key \'first\'', value = %s\n", ini->value(ini, "first"));ini->set_value(ini, "baidu", "hahaha");ini->save_to_file(ini, "write.conf");ini->remove(ini, "first");ini->save_to_file(ini, "write2.conf");delete_ini_parser(ini); }static void ini_parser_test_file() {struct ini_parser * ini = new_ini_parser();int size = ini->parse_file(ini, "test.conf");assert( size > 0);assert( ini->value(ini, "second") == 0 );assert( ini->value(ini, "abc") == 0);assert( ini->value(ini, "name") != NULL );assert( ini->value(ini, "first") != NULL);printf("ini string: %s\n", g_szIniString);printf("key-value pairs count = %d\n", size);printf("key \'name\'', value = %s\n", ini->value(ini, "name"));printf("key \'first\'', value = %s\n", ini->value(ini, "first"));printf("key \'baidu\'', value = %s\n", ini->value(ini, "baidu"));delete_ini_parser(ini); }void ini_parser_test() {ini_parser_test_string();ini_parser_test_file(); }
? ? 測試了解析字符串、文件、增、刪、寫文件,都沒什么大問題。
總結
以上是生活随笔為你收集整理的纯C语言INI文件解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎样提高深度睡眠时间,五个助眠小妙招帮助
- 下一篇: 热门博客