Разделить символ * на символ * Массив - PullRequest
0 голосов
/ 02 февраля 2012

Я пытаюсь разделить char * на массив char * в C. Я привык программировать на Java / PHP OO.Я знаю несколько простых способов сделать это на этих языках, но в Си ... я полностью потерян.У меня часто есть segfault для часов x)

Я использую TinyXML и получаю информацию из XML-файла.

Вот структура, где мы находим массив.

const int MAX_GATES = 64;

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

И вот где я заполняю эту структуру:

    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();

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

Единственная проблема - «ворота».Форма ввода XML выглядит как «gate1 / gate2 / gate3» или иногда пуста.

Я хочу, чтобы gate1 был в infos-> gates [0];и т. д. Я хочу иметь возможность впоследствии перечислить массив gates ..

У меня всегда есть ошибка, когда я пытаюсь.Кстати, я сейчас не знаю, как инициализировать этот массив указателей.Я всегда инициализирую все ворота [i] в ​​NULL, но мне кажется, что у меня есть ошибка, когда я делаю для (int i = 0; i

Спасибо за все.

Это нормально, когда я толькоуказатели, но когда String (char *) / Arrays / Pointers смешаны .. Я не могу справиться = P

Я тоже видел, что мы можем использовать что-то вроде int * myArray = calloc (NbOfRows, NbOfRows * sizeof (int)); Почему мы должны объявлять такой массив? .. x)

Спасибо!

1 Ответ

1 голос
/ 02 февраля 2012

Проблема, с которой люди часто сталкиваются с XML, заключается в том, что они предполагают, что все элементы доступны. Это не всегда безопасно. Таким образом, это утверждение:

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

Это небезопасно, потому что вы на самом деле не знаете, все ли функции фактически возвращают действительные объекты. Вам действительно нужно что-то как следующее (который не оптимизирован для скорости, как я не знать имя структуры tinyXML, возвращаемое в каждой точке и, таким образом, я не храню результаты один раз, а скорее вызываю каждую функцию несколько раз:

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

И затем, для защиты от переполнения буфера из данных, которые вы должны действительно делать:

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());
}

Разве вы не любите обработку ошибок?

Что касается другого вашего вопроса:

Я также видел, что мы можем использовать что-то вроде int * myArray = calloc (NbOfRows, NbOfRows * sizeof (int)); Почему мы должны объявлять массив как это.. ? х)

calloc сначала инициализирует полученную память 0, в отличие от malloc. Если вы видите выше, где я установил конец буфера в '\ 0' (что на самом деле 0), потому что malloc возвращает буфер с потенциально случайные (ненулевые) данные в нем. calloc сначала установит весь буфер сначала на все 0, что в целом может быть безопаснее.

...