C++编程之配置文件解析

2016-12-30 19:45:06来源:作者:人点击

第七城市

C++编程之配置文件解析:在实际项目中,经常会把软件的某些选项写入配置文件。 Windows 平台上的 INI 文件格式简单易用,设计了一个“类” ini_parser 来读写 INI 格式的配置文件。

struct ini_parser 可以解析 INI 格式的字符串、文件,也可以将内存中的符合 INI 格式的数据写入文件,能够支持 Windows 、Linux、Android等多平台。目前暂不支持选项分组功能。

功能相对简单,直接看源码吧。

下面是头文件:

 
structsingle_list;structini_parser{structsingle_list*keyvalues;int(*parse_file)(structini_parser*,constchar*file);int(*parse_string)(structini_parser*,constchar*text);char*(*value)(structini_parser*,constchar*key);void(*set_value)(structini_parser*,constchar*key,constchar*value);void(*remove)(structini_parser*,constchar*key);int(*save_to_file)(structini_parser*,constchar*file);void(*deletor)(structini_parser*ini);};structini_parser*new_ini_parser(); struct init_parser 的声明符合我们在本系列文章中提到的面向对象框架,需要说明的是,一旦 deletor 方法被调用, ini_parser 的实例将不再允许访问。下面是源文件:#include"ini_parser.h"#include#includestructtag_value_pair{structslist_nodenode;char*szTag;char*szValue;};typedefstructtag_value_pairtag_value;staticvoid_tag_value_free(structslist_node*node){if(node)delete_tag_value_pair(node);}staticint_tag_value_hittest(structslist_node*node,void*key){returnstrcmp((char*)tag,((structtag_value_pair*)node)->szTag);}staticstructsingle_list*new_tag_value_list(){returnnew_single_list(_tag_value_free,_tag_value_hittest);}staticstructtag_value_pair*new_tag_value_pair(){structtag_value_pair*pair=(structtag_value_pair*)malloc(sizeof(structtag_value_pair));pair->node.next=0;pair->szTag=0;pair->szValue=0;returnpair;}staticstructtag_value_pair*make_tag_value_pair(char*tag,char*value){structtag_value_pair*pair=0;if(!tag||!value)return0;pair=(structtag_value_pair*)malloc(sizeof(structtag_value_pair));pair->szTag=strdup(tag);pair->szValue=strdup(value);pair->node.next=0;returnpair;}staticstructtag_value_pair*parse_line(char*line,intlen){structtag_value_pair*pair=0;intcount=0;char*p=line;char*end=0;mchar*start=line;if(!p)return0;while(*p=='')++p;/*blankline*/if(p-line==len||*p=='/r'||*p=='/n'||*p=='/0')return0;/*donotsupportgroup*/if(*p=='[')return0;/*comments*/if(*p=='#')return0;/*extractkey*/start=p;end=line+len;while(*p!='='&&p!=end)++p;if(p==end){/*none'=',invalidline*/return0;}end=p-1;while(*end=='')--end;/*skipblankattheend*/count=end-start+1;pair=new_tag_value_pair();pair->szTag=malloc(count+1);strncpy(pair->szTag,start,count);pair->szTag[count]=0;/*extractvalue*/++p;end=line+len;/*nextposofthelastchar*/while(*p==''&&p!=end)++p;if(p==end){delete_tag_value_pair(pair);return0;}start=p;--end;/*tothelastchar*/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;}/*releaseemptykey-valuepair*/if(!pair->szValue){delete_tag_value_pair(pair);return0;}returnpair;}staticint_parse_file(structini_parser*ini,constchar*file){FILE*fp=fopen(file,"r");if(fp){structtag_value_pair*pair=0;charbuf[1024]={0};while(fgets(buf,1024,fp)){pair=parse_line(buf,strlen(buf));if(pair){ini->keyvalues->add(ini->keyvalues,pair);}}fclose(fp);returnini->keyvalues->size;}return-1;}staticint_parse_text(structini_parser*ini,constchar*text){char*p=text;char*start=0;structtag_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;}returnini->keyvalues->size;}staticchar*_value(structini_parser*ini,constchar*key){structtag_value_pair*pair=NODE_T(ini->keyvalues->find_by_key(ini->keyvalues,key),structtag_value_pair);if(pair)returnpair->szValue;return0;}staticvoid_set_value(structini_parser*ini,constchar*key,constchar*value){structtag_value_pair*pair=NODE_T(ini->keyvalues->find_by_key(ini->keyvalues,key),structtag_value_pair);if(pair){if(pair->szValue)free(pair->szValue);pair->szValue=strdup(value);}else{ini->keyvalues->add(ini->keyvalues,make_tag_value_pair(key,value));}}staticvoid_remove(structini_parser*ini,constchar*key){structtag_value_pair*pair=NODE_T(ini->keyvalues->find_by_key(ini->keyvalues,key),structtag_value_pair);if(pair)ini->keyvalues->remove(ini->keyvalues,pair);}staticvoidwrite_keyvalue(structtag_value_pair*pair,FILE*fp){fputs(pair->szTag,fp);fputc('=',fp);fputs(pair->szValue,fp);fputc('/n',fp);}staticint_save_to_file(structini_parser*ini,constchar*file){if(ini->keyvalues->size>0){FILE*fp=fopen(file,"w");if(fp){structtag_value_pair*pair=NODE_T(ini->keyvalues->head,structtag_value_pair);while(pair!=0){write_keyvalue(pair,fp);pair=NODE_T(pair->node.next,structtag_value_pair);}fclose(fp);return0;}}return-1;}staticvoid_delete_ini_parser(structini_parser*ini){if(ini){ini->keyvalues->deletor(ini->keyvalues);free(ini);}}structini_parser*new_ini_parser(){structini_parser*ini=(structini_parser*)malloc(sizeof(structini_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;ini->deletor=_delete_ini_parser;returnini;} 下面是简单的测试代码:view plaincopy在CODE上查看代码片派生到我的代码片staticchar*g_szIniString="#abc/nfirst=2/nsecond/nname=charlizhang/n";staticvoidini_parser_test_string(){structini_parser*ini=new_ini_parser();intsize=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("inistring:%s/n",g_szIniString);printf("key-valuepairscount=%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");ini->deletor(ini);}staticvoidini_parser_test_file(){structini_parser*ini=new_ini_parser();intsize=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("inistring:%s/n",g_szIniString);printf("key-valuepairscount=%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"));ini->deletor(ini);}voidini_parser_test(){ini_parser_test_string();ini_parser_test_file();}


struct ini_parser 已经运用在实际的项目中,目前为止没发现什么问题。

第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台