Search code examples
c++integertinyxml

tinyxml c++ using TiXmlText in storing integer data


as per the class reference the TixmlText takes const char* values as input. i need to store integer data read from a text file into xml. the integer data is stored in int vector and each element of the vector is converted to const char* before passing it to Tixml text function.

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

But when i finally see the generated xml document. i get garbage values in the element where i save the number

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

how do we store integer data properly?

i had traced the where the problem was happening to an extent in the tinyxml.h

class TiXmlNode : public TiXmlBase

the function

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
    }

where the value is of the same class TiXmlNode
being TIXML_STRING value;

  • Question: Am i missing some thing very simple?
  • Question: How can i store the integer data properly

Edit: Thanks for the answers from the docs a point which i missed Use the compile time define:

TIXML_USE_STL

to compile one version or the other. This can be passed by the compiler, or set as the first line of "tinyxml.h".

Note: If compiling the test code in Linux, setting the environment variable TINYXML_USE_STL=YES/NO will control STL compilation. In the Windows project file, STL and non STL targets are provided. In your project, It's probably easiest to add the line "#define TIXML_USE_STL" as the first line of tinyxml.h.

Tinyxml class ref


Solution

  • If you're compiling TinyXML with STL support (which you probably should be) TiXmlText also has a std::string constructor. As sekmet64 says, the memory allocated by the std::string for c_str() is released when the function exits so you are, in effect, returning a pointer to garbage.

    However, I would strongly recommend against allocating your own memory. Instead, return a std::string (which will take care of the memory for you):

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

    and then pass this into the TiXmlText constructor either as

    TiXmlText node(intToXmlChar(i));
    

    or as

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

    the latter case is ok because TiXmlText will take a copy of the temporary string before it is destroyed.

    In general stay away from conversion to a char* unless (or until) absolutely necessary, std::string is a safer and superior option the vast majority of the time.