【程序练习】——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来提醒程序写入父节点的结尾到文件中,所以还要加上一个写入父节点的语句;