1

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>
4

2 に答える 2

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 を再度使用して、より大きな文字列を貼り付けたい場合は、頑張ってください ;(

于 2013-08-14T19:25:07.363 に答える
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;
    }
}

sprintf ではなく strcpy を使用することもできることに注意してください

編集:

また、memset への呼び出しを取り除く必要があります。あなたがしようとしているのは、上記の NULL への割り当てのようなものですが、実際には有効なメモリである可能性がある 0xFFFFFFFF またはそのようなものであるため、-1 はポインターとして適切な値ではありません。

于 2013-08-14T19:13:38.217 に答える