tinyxml c ++ с использованием TiXmlText для хранения целочисленных данных

согласно ссылке на класс TixmlText принимает в качестве входных данных значения const char *. мне нужно сохранить целочисленные данные, прочитанные из текстового файла, в xml. целочисленные данные хранятся в векторе int, и каждый элемент вектора преобразуется в const char * перед передачей его в текстовую функцию Tixml.

const char* intToXmlChar(int num)
{
    stringstream abc;
    string value;
    abc<<num;
    value=abc.str();
    const char* ret_val = value.c_str();
    //char* conv_val = const_cast<char*>(ret_val);
    return ret_val;
}

Но когда я наконец вижу сгенерированный XML-документ. я получаю значения мусора в элементе, в котором я сохраняю число

<timestamp>1&#x00;504</timestamp>

как правильно хранить целочисленные данные?

Я проследил, где проблема возникла до некоторой степени в tinyxml.h

class TiXmlNode : public TiXmlBase

функция

void SetValue(const char * _value) {
printf(" pre ---number--- %s  using this \n",_value); //-- if the value is say 18504
 value = _value;
printf(" post ---number--- %s  using this \n",_value); //-- becomes 1&#x00;504 saved in xml
    }

где значение равно class TiXmlNode и равно TIXML_STRING value;

  • Вопрос: Я упустил очень простую вещь?
  • Вопрос: Как правильно хранить целочисленные данные

Изменить: Спасибо за ответы из документов, точку, которую я пропустил. Используйте определение времени компиляции:

TIXML_USE_STL

скомпилировать ту или иную версию. Это может быть передано компилятором или установлено как первая строка «tinyxml.h».

Примечание. При компиляции тестового кода в Linux установка переменной среды TINYXML_USE_STL = YES / NO будет управлять компиляцией STL. В файле проекта Windows предусмотрены цели STL и не STL. В вашем проекте , вероятно, проще всего добавить строку "#define TIXML_USE_STL" в качестве первой строки tinyxml.h.

Ссылка на класс Tinyxml


person Aditya P    schedule 24.03.2011    source источник


Ответы (3)


Если вы компилируете TinyXML с поддержкой STL (а вам, вероятно, и следовало бы быть), TiXmlText также имеет std::string конструктор. Как говорит sekmet64, память, выделенная std::string для c_str(), освобождается при выходе из функции, поэтому вы, по сути, возвращаете указатель на мусор.

Однако я настоятельно рекомендую не выделять собственную память. Вместо этого верните std :: string (который позаботится о памяти за вас):

std::string intToXmlChar(int num)
{
    std::stringstream abc;
    std::string value;
    abc<<num;
    return abc.str();
}

а затем передайте это в конструктор TiXmlText либо как

TiXmlText node(intToXmlChar(i));

or as

TiXmlText node(intToXmlChar(i).c_str());

в последнем случае все в порядке, потому что TiXmlText возьмет копию временной строки, прежде чем она будет уничтожена.

В общем, избегайте преобразования в char*, если (или до тех пор, пока) не будет абсолютно необходимо, std::string является более безопасным и превосходным вариантом в подавляющем большинстве случаев.

person Adam Bowen    schedule 24.03.2011
comment
Проблема в том, что я не компилирую с поддержкой stl. подскажите, как это сделать? библиотека находится на c, а моя программа на c ++. - person Aditya P; 24.03.2011
comment
Tiny XML - это библиотека C ++ (хотя и избегающая более сложных функций C ++). Чтобы включить поддержку STL, вам необходимо определить TIXML_USE_STL. С помощью GCC добавьте -DTIXML_USE_STL к флагам командной строки, с помощью MSVC ++ добавьте TIXML_USE_STL в определения препроцессора для вашего проекта. Важно, чтобы это определение всегда выполнялось до включения tinyxml.h. - person Adam Bowen; 24.03.2011
comment
Спасибо, также после того, как вы это сказали, я смог ясно увидеть этот момент в документе. Примечание. При компиляции тестового кода в Linux установка переменной среды TINYXML_USE_STL = YES / NO будет управлять компиляцией STL. В файле проекта Windows указаны цели как в STL, так и в других форматах. В вашем проекте, вероятно, проще всего добавить строку #define TIXML_USE_STL в качестве первой строки tinyxml.h. - person Aditya P; 24.03.2011

В C ++ я могу рекомендовать только TiCpp, облегченную оболочку над TinyXml с синтаксисом C ++.

Одно заметное улучшение: использование std::string :)

РЕДАКТИРОВАТЬ: чтобы получить источник, используйте следующую команду :

svn checkout http://ticpp.googlecode.com/svn/trunk/ ticpp-read-only
person Matthieu M.    schedule 24.03.2011
comment
я уже был на этой странице много раз раньше. Кажется, я не могу загрузить Ticpp, как вы выразились. единственная загрузка, которая происходит, - это испорченный файл chm. - person Aditya P; 24.03.2011
comment
Я использовал svn для получения исходников :) - person Matthieu M.; 24.03.2011

Проблема здесь:

const char* ret_val = value.c_str();

Из http://www.cplusplus.com/reference/string/string/c_str/ < / а>:

Возвращенный массив указывает на внутреннее расположение [...], но значения в этом массиве не должны изменяться в программе, и им разрешается только оставаться неизменными до следующего вызова непостоянной функции-члена строкового объекта.

Вместо этого вы можете скопировать массив символов с strcpy() в новый указатель, чтобы гарантировать, что он не будет изменен позже или удален при выходе из области видимости. Или еще лучше использовать функцию c для преобразования из int прямо в char *.

#include <stdlib.h>

char* intToXmlChar(int num)
{
    char *ret_val;
    itoa(num, ret_val, 10);
    return ret_val;
}

Я думаю, вы не сможете сделать это const, так как вам нужно его вычислить, только когда вы вызываете функцию

const char *a = intToXmlChar(2);
person sekmet64    schedule 24.03.2011
comment
Спасибо. я хотел избежать stdlib.h. @sekmet, у вас есть идея, как скомпилировать tinyxml с поддержкой stl? - person Aditya P; 24.03.2011
comment
Вставьте строку #define TIXML_USE_STL перед включением tinyxml.h или вставьте эту строку в начало tinyxml.h - person sekmet64; 24.03.2011
comment
+40 спасибо, секмет, я обнаружил это, когда Адам опубликовал свой метод. - person Aditya P; 24.03.2011