使用狀態機方式來拆分INI檔案,取出Group、Key Name、 Key Value等值
可用於字串解析
可用於字串解析
其中,註解以;開始,CRLF結束
INI範例:
; for 16-bit app support
[fonts]
[extensions]
[mci extensions]
[files]
[MCI Extensions.BAK]
aif=MPEGVideo
aifc=MPEGVideo
[annie]
CaptureFile=
VideoDevice=0
AudioDevice=0
FrameRate=333333
[SciCalc]
layout=0
static void ini_parse (char* buffer, char comment_char, char delim_char)
{
char* p = buffer;
char* group_start = NULL;
char* key_start = NULL;
char* value_start = NULL;
// 解析用的狀態
enum _State
{
STAT_NONE = 0,
STAT_GROUP,
STAT_KEY,
STAT_VALUE,
STAT_COMMENT
}state = STAT_NONE;
// 掃描整個文件內容
for(p = buffer; *p != '/0'; p++)
{
switch(state)
{
case STAT_NONE:
{
if(*p == '[')
{
// 進入Group狀態
state = STAT_GROUP;
group_start = p + 1;
}
else if(*p == comment_char)
{
// 注釋字元
state = STAT_COMMENT;
}
else if(!isspace(*p))
{
// 掃到Key值
state = STAT_KEY;
key_start = p;
}
break;
}
case STAT_GROUP:
{
// Group狀態結束
if(*p == ']')
{
*p = '/0';
state = STAT_NONE;
strtrim(group_start);
printf("[%s]/n", group_start);
}
break;
}
case STAT_COMMENT:
{
// 注釋狀態結束
if(*p == '/n')
{
state = STAT_NONE;
break;
}
break;
}
case STAT_KEY:
{
// Key名稱讀取完成,開始讀取其值
if(*p == delim_char || (delim_char == ' ' && *p == '/t'))
{
*p = '/0';
state = STAT_VALUE;
value_start = p + 1;
}
break;
}
case STAT_VALUE:
{
// 讀取Key值
if(*p == '/n' || *p == '/r')
{
*p = '/0';
state = STAT_NONE;
strtrim(key_start);
strtrim(value_start);
printf("%s%c%s/n", key_start, delim_char, value_start);
}
break;
}
default:break;
}
}
if(state == STAT_VALUE)
{
strtrim(key_start);
strtrim(value_start);
printf("%s%c%s/n", key_start, delim_char, value_start);
}
return;
}