Reputation: 29
I'm currently learning how to program and i'm pretty sure my code is filled with errors.
I have a segmentation fault when executing this code and i don't know why.
#include <stdio.h>
#include <libxml/parser.h>
#include <string.h>
#include <stdlib.h>
typedef struct
{
int ac; /**< The player armor class. */
char *class; /**< The player class. */
char *cname; /**< The player character name. */
int cp; /**< The player money (copper pieces, 100 CP = 1 GP). */
int gp; /**< The player money (gold pieces). */
int hp; /**< The player hit points. */
char *name; /**< The player name. */
int sp; /**< The player money (silver pieces, 10 SP = 1 GP). */
} player_t;
void parsePlayer(xmlDocPtr doc, xmlNodePtr node){
int i = 1;
player_t players[3];
xmlNodePtr cur;
node = node->xmlChildrenNode;
while(node!=NULL){
if (!xmlStrcmp(node->name, (const xmlChar *) "player"))
{
players[i].name = (char *) xmlGetProp(node, (const xmlChar *)"name");
printf("player %d name: %s\n", i, players[i].name);
cur = node->xmlChildrenNode;
players[i].ac = strtol((char *) xmlNodeListGetString(doc, cur->xmlChildrenNode, 1),NULL,10);
i++;
}
node = node->next;
}
}
void parsePlayers(xmlDocPtr doc){
xmlNodePtr node;
node = xmlDocGetRootElement(doc);
node = node->xmlChildrenNode;
while(node!=NULL){
if (!xmlStrcmp(node->name, (const xmlChar *) "players")){
parsePlayer(doc, node);
}
node = node->next;
}
}
int main(int argc, char const *argv[]) {
xmlDocPtr doc = xmlParseFile(argv[1]);
if (doc != NULL) printf("DEBUG: File parsed.\n");
else {
fprintf(stderr,"Unable to parse the document \n");
return 1;
}
parsePlayers(doc);
return 0;
}
The code display this :
DEBUG: File parsed.
player 1 name: Camille /* correct */
Segmentation Fault
I've tried looking for answers but it seems i'm not advanced enough to understand them :/.
This is for a project in school (i have to fill several player_t structures).
I don't think the error comes from the XML so no need to post it here.
I've been stuck on this error for a few days now and i'd love to understand how to correct it.
Thanks for reading :).
EDIT: Thanks for your answer, gdb says :
Program received signal SIGSEGV, Segmentation fault.
__GI_____strtol_l_internal (nptr=0x0, endptr=0x0, base=10, group=<optimized out>,
loc=0x7ffff7a0f560 <_nl_global_locale>) at ../stdlib/strtol_l.c:292
292 ../stdlib/strtol_l.c: no such file or directory.
I have no idea what this means :(.
EDIT 2: Ok, the error was indeed from the xml, here it is :
<ddg name="The frozen cave">
<date>
<day>01</day>
<month>09</month>
<year>2019</year>
</date>
<dmname>Pierre</dmname>
<players>
<player name="Camille">
<ac>5</ac>
<class>Thief</class>
<cname>Camigolas</cname>
<hp>4</hp>
<money>
<cp>10</cp>
<gp>10</gp>
<sp>10</sp>
</money>
</player>
<player name="Jean">
<ac>4</ac>
<class>Fighter</class>
<cname>Jeragorn</cname>
<hp>8</hp>
<money>
<cp>3</cp>
<gp>1</gp>
<sp>2</sp>
</money>
</player>
<player name="Paul">
<ac>5</ac>
<class>Cleric</class>
<cname>Paumli</cname>
<hp>6</hp>
<money>
<cp>9</cp>
<gp>5</gp>
<sp>9</sp>
</money>
</player>
</players>
</ddg>
I've tried several things and ended up discovering that the xmlChildrenNode of player is text.
I guess i just need to loop until i find the element i want but does anyone knows why it returns text ? (i just printf cur->name to discover that).
Thank you all for you answers :)!
Upvotes: 0
Views: 724
Reputation: 1762
I've tried several things and ended up discovering that the xmlChildrenNode of player is text. I guess i just need to loop until i find the element i want but does anyone knows why it returns text
All whitespace between elements in XML files is significant. The <Player> node will have 11 node children:
So that first "text" child you're seeing under <Player> is the newline and spaces that occur before <ac>.
You may want to pass XML_PARSE_NOBLANKS into xmlParseFile, which tells the parser to skip over "in-between" whitespace like this. Then <Player> will have the <ac> child, then the <class> child, etc. without the text nodes between.
Upvotes: 1
Reputation: 2188
nptr=0x0
probably means that strtol
(or more presisely the function that was called by strtol
) was called with the parameter nptr
set to 0x0
. The parameters nptr
was most like expected to point to a valid string, but didn't.
What that likely means, is that xmlNodeListGetString()
returns zero or NULL
, depending on how you prefer to call the value.
When parsing external files, you should ALWAYS do error checking of the file content.
I would guess that cur->xmlChildrenNode
doesn't have the value you expect it to, but it is hard to say without more info.
And by the way, c
is one of those languages that has zero based arrays, so you should have int i = 0
. (One based arrays are evil.) Do not be a heretic by simulating one-based arrays by having a dummy-element at players[0]
.
Upvotes: 1