简体   繁体   中英

Split char* to char * Array

I'm trying to split a char* to an array of char* in C. I'm used to program in Java / PHP OO. I know several easy way to do that in these languages but in C... I'm totally lost. I often have segfault for hours x)

I'm using TinyXML and getting info from XML File.

Here's the struct where we find the array.

const int MAX_GATES = 64;

typedef struct {
    char *name;
    char *firstname;
    char *date;
    char *id;
    char *gates[MAX_GATES];
} UserInfos;

And here's where I fill this struct :

    UserInfos * infos = (UserInfos*)malloc(1024);

    infos->firstname = (char*)malloc(256);
    infos->name = (char*)malloc(128);
    infos->id = (char*)malloc(128);
    infos->date = (char*)malloc(128);

    sprintf(infos->firstname, "%s", card->FirstChild("firstname")->FirstChild()->Value());
    sprintf(infos->name, "%s", card->FirstChild("name")->FirstChild()->Value());
    sprintf(infos->date, "%s", card->FirstChild("date")->FirstChild()->Value());
    sprintf(infos->id, "%s", card->FirstChild("filename")->FirstChild()->Value());

    ////////////////////////
    // Gates
    char * gates = (char*) card->FirstChild("gates")->FirstChild()->Value();

    //////////////////////////

The only problem is on 'gates'. The input form XML looks like "gate1/gate2/gate3" or just blank sometimes.

I want gate1 to be in infos->gates[0] ; etc. I want to be able to list the gates array afterwards..

I always have a segfault when I try. Btw, I don't really now how to initialize this array of pointers. I always initialize all gates[i] to NULL but It seems that I've a segfault when I do for(int i=0;i

Thanks for all.

It's OK when I've only pointers but when String(char*) / Arrays / Pointers are mixed.. I can't manage =P

I saw too that we can use something like int *myArray = calloc(NbOfRows, NbOfRows*sizeof(int)); Why should we declare an array like that.. ? x)

Thanks!

The problem that people frequently have with XML is that they assume all the elements are available. That's not always safe. Thus this statement:

sprintf(infos->firstname, "%s", card->FirstChild("firstname")->FirstChild()->Value());

Isn't safe to do because you don't actually know if all of those functions actually return valid objects. You really need something like the following (which is not optimized for speed, as I don't know the tinyXML structure name being returned at each point and thus am not storing the results once and am rather calling each function multiple times:

if (card->FirstChild("firstname") &&
   card->FirstChild("firstname")->FirstChild()) {
   sprintf(infos->firstname, "%s", card->FirstChild("firstname")->FirstChild()->Value());
}

And then, to protect against buffer overflows from the data you should really be doing:

if (card->FirstChild("firstname") &&
   card->FirstChild("firstname")->FirstChild()) {
   infos->firstname[sizeof(infos->firstname)-1] = '\0';
   snprintf(infos->firstname, sizeof(infos->firstname)-1, "%s", card->FirstChild("firstname")->FirstChild()->Value());
}

Don't you just love error handling?

As to your other question:

I saw too that we can use something like int *myArray = calloc(NbOfRows, NbOfRows*sizeof(int)); Why should we declare an array like that.. ? x)

calloc first initializes the resulting memory to 0, unlike malloc. If you see above where I set the end of the buffer to '\\0' (which is actually 0), that's because malloc returns a buffer with potentially random (non-zero) data in it. calloc will first set the entire buffer to all 0s first, which can be generally safer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM