我刚刚解析了xml并将其中的值插入到char数组中。但是在打印时我得到了一些不同的输出如下。
ȷ
�,
��
但实际上它应该是
Alu Tomato
Baigan Bharta
Chicken 65
源代码:
#include<stdio.h>
#include<string.h>
#include<libxml/parser.h>
#include<libxml/tree.h>
static void print_element_names(xmlNode * a_node);
char node_name[1024] = "";
char *menu_list[200];
int no_of_item = 0;
char tempstr[1024];
int flag_node = 0;
int main ()
{
memset (menu_list, -1, sizeof(menu_list));
parsexml();
printMenuList();
return 0;
}
int parsexml()
{
xmlDoc *doc = NULL;
xmlNode *root_element = NULL;
const char *Filename = "/mnt/jffs2/temp.xml";
doc = xmlReadFile(Filename, NULL, 0);
if (doc == NULL)
{
printf("error: could not parse file %s\n", Filename);
}
else
{
root_element = xmlDocGetRootElement(doc);
print_element_names(root_element);
xmlFreeDoc(doc);
}
xmlCleanupParser();
return 0;
}
static void print_element_names(xmlNode * a_node)
{
xmlNode *cur_node = NULL;
for (cur_node = a_node; cur_node; cur_node = cur_node->next)
{
if (cur_node->type == XML_ELEMENT_NODE)
{
sprintf(node_name, "%s", cur_node->name);
if(strcmp(cur_node->name,"itemName") == 0)
flag_node = 1;
}
if(cur_node->content!=NULL)
{
if(flag_node == 1)
{
printf("Items\t%s\n", cur_node->content);
sprintf(menu_list[no_of_item], "%s", cur_node->content);
//menu_list[no_of_item] = cur_node->content;
flag_node = 0;
no_of_item++;
}
}
print_element_names(cur_node->children);
}
}
int printMenuList()
{
int i;
for (i=0; i<no_of_item; i++)
{
printf("%s\n", menu_list[i]);
}
return 0;
}
我的xml
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<userloginMethodResponse xmlns="http://wsdlclass.wsdlcreat.sims.triesten.com">
<userloginMethodReturn>
<itemCode>ALT</itemCode>
<itemName>Alu Tomato</itemName>
<itemPrice>0.0</itemPrice>
<loginStatusId>0</loginStatusId>
<loginid xsi:nil="true"/>
<messId>1</messId>
<password xsi:nil="true"/>
<schoolId>1</schoolId>
<userId>60000100</userId>
</userloginMethodReturn>
<userloginMethodReturn>
<itemCode>BAI</itemCode>
<itemName>Baigan Bharta</itemName>
<itemPrice>0.0</itemPrice>
<loginStatusId>0</loginStatusId>
<loginid xsi:nil="true"/>
<messId xsi:nil="true"/>
<password xsi:nil="true"/>
<schoolId>0</schoolId>
<userId xsi:nil="true"/>
</userloginMethodReturn>
<userloginMethodReturn>
<itemCode>CHIKK</itemCode>
<itemName>Chicken 65</itemName>
<itemPrice>20.0</itemPrice>
<loginStatusId>0</loginStatusId>
<loginid xsi:nil="true"/>
<messId xsi:nil="true"/>
<password xsi:nil="true"/>
<schoolId>0</schoolId>
<userId xsi:nil="true"/>
</userloginMethodReturn>
</userloginMethodResponse>
</soapenv:Body>
</soapenv:Envelope>
答案 0 :(得分:2)
你需要像
这样的东西#define MENU_STR_SIZE 64
宣布menu_list时:
char * menu_list[200] = {NULL};
然后,在您使用sprintf将字符串添加到menu_list
的循环中if (menu_list[no_of_item] == NULL){
if ( (menu_list[no_of_item] = malloc(MENU_STR_SIZE)) == NULL)
printf("Memory Error!!\n"); /*do some cleanup or quit or whatever you choose*/
}
sprintf(menu_list[no_of_item], "%s", cur_node->content);
然后,您需要添加一个功能来释放菜单列表
void menu_list_free(char ** menu_list, int size)
{
int i;
for ( i = 0; i < size; i++ ){
if (menu_list[i])
free (menu_list[i]);
menu_list[i] = NULL;
}
}
请注意,您也可以使用strcpy而不是sprintf
编辑:
您还需要摆脱对memset的调用。你要做的就像我上面的NULL分配,但-1对于指针来说不是一个好的值,因为它可能是0xFFFFFFFF或类似的东西,它实际上可能是有效的内存。
答案 1 :(得分:2)
menu_list未分配。
使这个程序有效的最简单的改变是:
< sprintf(menu_list[no_of_item], "%s", cur_node->content);
--
> menu_list[no_of_item] = strdup(cur_node->content);
这将在合适的时间完成分配。
有了这个改变,我得到了
amrith@amrith-vbox:/tmp$ ./xx
Items Alu Tomato
Items Baigan Bharta
Items Chicken 65
Alu Tomato
Baigan Bharta
Chicken 65
amrith@amrith-vbox:/tmp$
我没有尝试释放内存,如果有人想再次使用menu_list并在其中粘贴更大的字符串,祝你好运;(