【程序练习】——ini格式转换为xml格式

;Configuration of http
[http]
doamin=www.mysite.com
port=8080
cgihome=/cgi-bin
 
;Configuration of db
[database]
server = mysql
user = myname
password = toopendatabase

转换为:

 1 <!-- Configuration of http -->
 2 <http>
 3    <doamin>www.mysite.com</doamin>
 4    <port>8080</port>
 5    <cgihome>/cgi-bin</cgihome>
 6 </http>
 7  
 8 <!-- Configuration of db -->
 9 <database>
10    <server>mysql</server>
11    <user>myname</user>
12    <password>toopendatabase</password>
13 </database>
 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <errno.h>
 4 #include <stdlib.h>
 5 
 6 void INI_to_XML()
 7 {
 8     FILE *ini,*xml;            //声明两个文件流
 9     //声明两个缓冲区
10     char buf[100];            //存放父节点,即http,database
11     char dbuf[100];            //存放子节点和子节点的值,即doamin=www.mysite.com```````
12     char ch;                        //定义一个变量用来获取文件的当前位置字符
13     int i = 0;
14     char *kay,*value;        //用来分割子节点和子节点的值用到的指针
15 
16     if((ini = fopen("inifile.txt","r")) == NULL){        //打开源文件
17         perror("open inifile.txt");
18         exit(1);
19     }
20 
21     if((xml = fopen("xml","aw+")) == NULL){            //打开目标文件
22         perror("open xml");
23         exit(1);
24     }
25 
26     while((ch = fgetc(ini)) != EOF){                        //一直读到文件的末尾
27         if(ch == ';'){                                                        //根据源文件特性进行判断
28             i = 0;
29             memset(buf,0,sizeof(buf));                            //初始化缓存区
30             while((ch = fgetc(ini)) != '\r')                //windows下的文件一行的结束符用‘\r’'\n'来表示
31                 buf[i++] = ch;
32             fseek(ini,1,SEEK_CUR);                                    //把文件指针偏移到下一行
33             fprintf(xml,"<!--%s-->\n",buf);                    //把缓冲区的数据写入文件
34             continue;
35         }
36 
37         if(ch == '['){
38             i = 0;
39             memset(buf,0,sizeof(buf));
40             while((ch = fgetc(ini)) != ']')
41                 buf[i++] = ch;
42             fseek(ini,2,SEEK_CUR);
43             fprintf(xml,"<%s>\n",buf);
44             continue;
45         }
46         if(ch != '\n' && ch != '\r' && ch != ' '){
47             memset(dbuf,0,sizeof(buf));
48             i = 0;
49             while((ch = fgetc(ini)) != '\r')
50                 dbuf[i++] = ch;
51             kay = strtok(dbuf,"=");                                    //分割字符串
52             value = strtok(NULL,"=");
53             fprintf(xml,"\t<%s>%s</%s>\n",kay,value,kay);
54             fseek(ini,1,SEEK_CUR);
55             continue;    
56         }
57         if(ch == '\n')                                                //当子节点和其值全部写入文件后,即把父节点的结尾补全
58             fprintf(xml,"</%s>\n",buf);
59             
60     }
61     fprintf(xml,"</%s>\n",buf);                    //把最后一个父节点结尾写入到文件
62     
63     //关闭文件
64     fcolse(xml);
65     fcolse(ini);
66 }
67 
68 int main(int argc, char *argv[])
69 {
70     INI_to_XML();
71     return 0;
72 }

关于代码中文件偏移的解释;

  由于此ini格式的文件在windows下编辑的时候会按照windows的模式格式化文件,会在每行的结尾添加‘\r’'\n'。因此ini文件转换成字符串应该是:

;Configuration of http\r\n[http]\r\ndomain=www.mysite.com\r\nport=8080\r\ncgihome=/cgi-bin\r\n

\r\n

;Configuration of db\r\n[database]\r\nserver = mysql\r\nuser = myname\r\npassword = toopendatabase\r\n

 

如果不设置文件偏移,父节点的结束符很难写入到文件中,当用到了文件偏移的时候,每次读取完需要的数据时候就会把文件中的\r\n 略过从而使文件直接读取下一个有效字符,当段数据全部写入文件时

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

全部写入文件时,此时文件有一个空行,也就是多出了一对\r\n 这时候我们就可以用这对\r\n 来判断什么时候写入父节点的结尾。

还需要注意的是,当文件读取完之后,就不会再有多余的\r\n来提醒程序写入父节点的结尾到文件中,所以还要加上一个写入父节点的语句;

posted @ 2013-06-24 01:19  net小伙  阅读(2631)  评论(0编辑  收藏  举报