用有限状态机实现INI和XML的转换

  写了个INI转化为XML的小程序,利用有限状态机实现的。很简单,把INI文件中的内容一行一行地读取进一个buffer里面,然后对这个buffer进行解析,最后转化为XML的格式再写进XML文件里面。

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
#include < stdio.h >
#include
< stdlib.h >
#include
< string .h >

#define BUFFER_SIZE 512
#define TRUE 1
#define FALSE 0

typedef
enum _state
{
STATE_NONE
= 0 ,
STATE_COMMENT,
STATE_SECTION,
STATE_SECTION_END,
STATE_KEY,
} stateType;

char gSection[BUFFER_SIZE];

static int gSectionIsEmpty( void )
{
for ( int index = 0 ; index < BUFFER_SIZE; ++ index)
{
if (gSection[index] != 0x00 )
{
return FALSE;
}
}
return TRUE;
}

static stateType getStateType( const char ch)
{
stateType state
= STATE_NONE;
if (ch == ' ; ' )
state
= STATE_COMMENT;
else if (ch == ' [ ' )
state
= STATE_SECTION;
else if (ch == ' \0 ' || ch == ' \n ' || ch == ' ' || ch == ' \t ' )
state
= STATE_SECTION_END;
else
state
= STATE_KEY;
return state;
}

#define KEY_LEN 128
#define VALUE_LEN 256
static void parse_key_and_value( const char * line, char * buffer)
{
char key[KEY_LEN] = { 0 };
char value[VALUE_LEN] = { 0 };

for ( int index = 0 ; * line != ' \0 ' ; ++ line)
{
if ( * line != ' \t ' && * line != ' ' && * line != ' = ' )
{
key[index
++ ] = * line;
}
else
{
key[index]
= ' \0 ' ;
break ;
}
}
for (; * line != ' \0 ' ; ++ line)
{
if ( * line == ' \t ' || * line == ' ' || * line == ' = ' )
continue ;
else
break ;
}
for ( int index = 0 ; * line != ' \0 ' ; ++ line)
{
if ( * line != ' \t ' && * line != ' ' && * line != ' = ' )
{
value[index
++ ] = * line;
}
else
{
value[index]
= ' \0 ' ;
break ;
}
}

sprintf(buffer,
" \t<%s>%s</%s>\n " , key, value, key);
return ;
}

static void iniParse( const char * line, FILE * fpXML)
{
char writeBuffer[BUFFER_SIZE] = { 0 };
stateType state
= getStateType( * line);

switch (state)
{
case STATE_COMMENT:
line
++ ;
sprintf(writeBuffer,
" <!-- %s -->\n " , line);
fwrite(writeBuffer, strlen(writeBuffer),
1 , fpXML);
break ;

case STATE_SECTION:
line
++ ;
for ( int index = 0 ; index < BUFFER_SIZE && * line != ' \0 ' ; ++ line)
{
if ( * line != ' ] ' )
{
gSection[index
++ ] = * line;
}
else
{
gSection[index]
= ' \0 ' ;
sprintf(writeBuffer,
" <%s>\n " , gSection);
fwrite(writeBuffer, strlen(writeBuffer),
1 , fpXML);
}
}
break ;

case STATE_SECTION_END:
if (gSectionIsEmpty() == FALSE)
{
sprintf(writeBuffer,
" </%s>\n\n " , gSection);
fwrite(writeBuffer, strlen(writeBuffer),
1 , fpXML);
memset(gSection,
0x00 , sizeof (gSection));
}
break ;

case STATE_KEY:
parse_key_and_value(line, writeBuffer);
fwrite(writeBuffer, strlen(writeBuffer),
1 , fpXML);
break ;

default :
break ;
}
return ;
}

static void createXML( const char * iniName, char * xml)
{
for ( int index = 0 ; index < 20 ; ++ index)
{
if (iniName[index] != ' . ' && iniName[index] != ' \0 ' )
{
xml[index]
= iniName[index];
}
else
{
strcat(xml,
" .xml " );
break ;
}
}
return ;
}

static void writeTheLastSectionEnd(FILE * fpXML)
{
char writeBuffer[BUFFER_SIZE] = { 0 };
sprintf(writeBuffer,
" </%s>\n\n " , gSection);
fwrite(writeBuffer, strlen(writeBuffer),
1 , fpXML);
return ;
}

static void iniToxml( const char * iniName)
{
char xmlName[ 20 ] = { 0 };
createXML(iniName, xmlName);

FILE
* fpINI = fopen(iniName, " r " );
FILE
* fpXML = fopen(xmlName, " a+ " );
if (fpINI == NULL || fpXML == NULL)
{
fprintf(stderr,
" open ini/xml file failed.\n " );
return ;
}

char line[BUFFER_SIZE] = { 0 };
while (fgets(line, BUFFER_SIZE, fpINI))
{
line[strlen(line)
- 1 ] = ' \0 ' ;
iniParse(line, fpXML);
memset(line,
0x00 , sizeof (line) );
}
writeTheLastSectionEnd(fpXML);

fclose(fpINI);
fclose(fpXML);
return ;
}

int main( int argc, char * argv[])
{
if (argc < 2 )
{
fprintf(stdout,
" usage: ./iniToxml <*.ini> (<*.ini>, ...) " );
return - 1 ;
}

for ( int i = 1 ; i < argc; ++ i)
{
iniToxml(argv[i]);
}
return 0 ;
}
测试的一个INI文件为:

 
  
;Configuration of http
[http]
domain
= www.mysite.com
port
= 8080
cgihome
=/ cgi - bin

;Configuration of db
[database]
server
= mysql
user
= myname
password
= toopendatabase
转化后的XML文件为:

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
<!-- Configuration of http -->
< http >
< domain > www.mysite.com </ domain >
< port > 8080 </ port >
< cgihome >/ cgi - bin </ cgihome >
</ http >

<!-- Configuration of db -->
< database >
< server > mysql </ server >
< user > myname </ user >
< password > toopendatabase </ password >
</ database >

 

END

转载于:https://www.cnblogs.com/python_newbie/archive/2010/08/09/1796074.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值