在学习C语言文件操作时,遇到这样一个题目:

编写示例程序,把数据从文本文件中读取出来,并解析xml,存入struct st_girl结构体中,然后在界面上显示出来。

文本文件的内容如下:

android xml拼接字符串 xml字符串解析_数据

解决此题的大致思路:首先创建一个字符串数组用于存放从文本文件中读取到的数据,随后使用fgets函数逐行读取文件中的数据,读一行解析一行,最后存入相应的结构体数组。

为解析xml字符串,编写了以下核心函数:

/*
*函数功能:从xml字符串中解析出相应的数据(姓名等)
*函数参数:in_XMLBuffer  xml字符串首地址
*		  in_FiledName  标签名
*		  out_Value 解析结果存放的地址
*/
int GetXMLBuffer_Str(char* in_XMLBuffer,char* in_FiledName,char* out_Value)
{
	//如果out_Value是空地址,直接返回
	if(out_Value ==0)
		return -1;
	
	int m_NameLen = strlen(in_FiledName);  //记录字段标签长度,如name标签的长度
	
	char* start = 0;  //记录开始标签的位置
	char* end = 0;    //记录结束标签的位置
	char m_SFiledName[51],m_EFiledName[51];  //字段的开始标签和结束标签
	
	//初始化
	memset(m_SFiledName,0,sizeof(m_SFiledName));
	memset(m_EFiledName,0,sizeof(m_EFiledName));
	
	//函数原型int snprintf(char *str, size_t size, const char *format, ...)
	//snprintf函数将可变个参数(...)按照format格式化成字符串,然后将其复制到str中
	snprintf(m_SFiledName,50,"<%s>",in_FiledName);	//利用snprintf将name写入开始标签中<name>
	snprintf(m_EFiledName,50,"</%s>",in_FiledName);	//利用snprintf将name写入结束标签中</name>
	
	start = 0,end = 0;
	/*
	 *extern char *strstr(char *str1, const char *str2);
	 *	语法:
     * 	strstr(str1,str2)
	 *	str1: 被查找目标 
     *  str2: 要查找对象 
	 *  返回值:若str2是str1的子串,则返回str2在str1的首次出现的地址;
	 *          如果str2不是str1的子串,则返回NULL。
	 */
	start = (char*)strstr(in_XMLBuffer,m_SFiledName);
	if(start!=0)
	{
		/* 如果start不为0,再根据strstr函数找end位置,这里strstr的第一个参数用start就可以,
		 *不用再传入in_XMLBuffer从头再找,直接从start位置找更加省时间。
		*/
		end = (char*)strstr(start,m_EFiledName);
	}
	//判断start和end的值 若为0直接返回
	if((start == 0)||(end == 0))
		return -1;
	
	//记录要解析的字段的长度
	int m_ValueLen = end - start - m_NameLen - 2;
	
	strncpy(out_Value,start + m_NameLen + 2,m_ValueLen);
	
	out_Value[m_ValueLen] = 0;
	
	return 0;	
}

整体代码:

/*
 * 解析xml,存入struct st_girl结构体中,然后在界面上显示出来。
 *<name>西施</name><age>20</age><height>166</height><sc>一般</sc><yz>漂亮</yz>
 */

#include<stdio.h>
#include<string.h>
#include <stdlib.h>

int GetXMLBuffer_Str(char* in_XMLBuffer,char* in_FiledName,char* out_Value);
int GetXMLBuffer_Int(char *in_XMLBuffer,char *in_FiledName,int *out_Value);


struct st_girl{
	char name[50];
	int age;
	int height;
	char sc[30];
	char yz[30];
}stgirl[5];

int main()
{
	FILE* fp = 0;
	char strbuf[301];     //用于存放xml格式字符串
	if((fp = fopen("stgirl.txt","rt")) ==0)
	{
		printf("打开文件失败!\n");
		return -1;
	}
		
	//fgets函数逐行读取文件中的数据
	/*
	 *读一行解析一行,然后存入结构体数组
	 */
	int i = 0;
	while(1)
	{
		if(fgets(strbuf,301,fp)==0)
			break;
		GetXMLBuffer_Str(strbuf,"name",stgirl[i].name);  //姓名
		GetXMLBuffer_Int(strbuf,"age",&stgirl[i].age);  //年龄
		GetXMLBuffer_Int(strbuf,"height",&stgirl[i].height);  //身高
		GetXMLBuffer_Str(strbuf,"sc",stgirl[i].sc);  //身材
		GetXMLBuffer_Str(strbuf,"yz",stgirl[i].yz);  //颜值	
		
		printf("第%d位超女信息:\n",i+1);
		printf("姓名:%s,年龄:%d,身高:%d,身材:%s,颜值:%s",stgirl[i].name,stgirl[i].age,stgirl[i].height,stgirl[i].sc,stgirl[i].yz);
		printf("\n");
		
		i++;
	}
	fclose(fp);
	
	return 0;
}

int GetXMLBuffer_Str(char* in_XMLBuffer,char* in_FiledName,char* out_Value)
{
	//如果out_Value是空地址,直接返回
	if(out_Value ==0)
		return -1;
	
	int m_NameLen = strlen(in_FiledName);  //记录字段标签长度,如name标签的长度
	
	char* start = 0;  //记录开始标签的位置
	char* end = 0;    //记录结束标签的位置
	char m_SFiledName[51],m_EFiledName[51];  //字段的开始标签和结束标签
	
	//初始化
	memset(m_SFiledName,0,sizeof(m_SFiledName));
	memset(m_EFiledName,0,sizeof(m_EFiledName));
	
	//函数原型int snprintf(char *str, size_t size, const char *format, ...)
	//snprintf函数将可变个参数(...)按照format格式化成字符串,然后将其复制到str中
	snprintf(m_SFiledName,50,"<%s>",in_FiledName);	//利用snprintf将name写入开始标签中<name>
	snprintf(m_EFiledName,50,"</%s>",in_FiledName);	//利用snprintf将name写入结束标签中</name>
	
	start = 0,end = 0;
	/*
	 *extern char *strstr(char *str1, const char *str2);
	 *	语法:
     * 	strstr(str1,str2)
	 *	str1: 被查找目标 
     *  str2: 要查找对象 
	 *  返回值:若str2是str1的子串,则返回str2在str1的首次出现的地址;
	 *          如果str2不是str1的子串,则返回NULL。
	 */
	start = (char*)strstr(in_XMLBuffer,m_SFiledName);
	if(start!=0)
	{
		/* 如果start不为0,再根据strstr函数找end位置,这里strstr的第一个参数用start就可以,
		 *不用再传入in_XMLBuffer从头再找,直接从start位置找更加省时间。
		*/
		end = (char*)strstr(start,m_EFiledName);
	}
	//判断start和end的值 若为0直接返回
	if((start == 0)||(end == 0))
		return -1;
	
	//记录要解析的字段的长度
	int m_ValueLen = end - start - m_NameLen - 2;
	
	strncpy(out_Value,start + m_NameLen + 2,m_ValueLen);
	
	out_Value[m_ValueLen] = 0;
	
	return 0;	
}

GetXMLBuffer_Int(char *in_XMLBuffer,char *in_FiledName,int *out_Value)
{
	char strvalue[51];
	memset(strvalue,0,sizeof(strvalue));
	
	if(GetXMLBuffer_Str(in_XMLBuffer,in_FiledName,strvalue)!=0)
		return -1;
	
	/*
	 *函数原型:int atoi(const char* nptr).
	 *函数功能:把字符串转换成整型数,ascii to integer
	 *			函数会扫描参数 nptr字符串,会跳过前面的空白字符(例如空格,tab缩进)等。
	 *			如果 nptr不能转换成 int 或者 nptr为空字符串,那么将返回 0
	 */
	(*out_Value) = atoi(strvalue);
	
	return 0;
}

程序运行结果:

android xml拼接字符串 xml字符串解析_数据_02