C程序:数组推送错误

时间:2013-08-14 18:48:40

标签: c xml arrays char

我刚刚解析了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>

2 个答案:

答案 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并在其中粘贴更大的字符串,祝你好运;(