程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++編程之配置文件解析

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

編輯:關於C++

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"

#includ
e
#include

structtag_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;m
char*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 已經運用在實際的項目中,目前為止沒發現什麼問題。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved