ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  A little problem to dynamically set the const char* array of labels in c++
Posted by Nico on Aug-17-2004 08:36
Hi,
I have a little problem to dynamically set the const char* array of labels in c++ when I try to use the PieChart.
With the XY Charts I use the addLabel() function so I can resolve the problem.
I read the data in a database and I don't know what is the numbers of the elements and what is the value of the elements before I open the database, so I need to write a portion of code that add the values in an array.
Can you help me, please?

  Re: A little problem to dynamically set the const char* array of labels in c++
Posted by Peter Kwan on Aug-17-2004 22:37
Hi Nico,

Typically, you just read in the data into a variable size vector. When you finished reading, you just copy the vector into an array. For example:

std::vector<std::string> buffer;

while (.... in the database loop ....)
{
    char *label = ... code to read one label from database ....

    //save the buffer
    buffer.push_back(label);
}

//now create the array
const char* const* labels = new (const char*)[buffer.size()];
for (int i = 0; i < buffer.size(); ++i)
    labels[i] = buffer[i].c_str();

//use in setLabels like:
c->setLabels(myData, StringArray(labels, buffer.size()));

//of course, remember to free data in C++
delete[] labels;


Regards
Peter Kwan

  Re: A little problem to dynamically set the const char* array of labels in c++
Posted by Nico on Aug-19-2004 21:13
Hi Peter,
thanks a lot.

  Re: A little problem to dynamically set the const char* array of labels in c++
Posted by Mitch Haas on Apr-17-2009 08:49
I agree!  Thanks Peter, for the code above to convert from a std::vector<std::string> to
a StringArray.  It works like a charm.

I created a C++ class (more of a function object, really) to perform your algorithm inline,
Using this class also removes the need to deallocate the char array manually.
I thought I'd post it here for anyone using C++ who needs it.

It's simple to use. The name of the class is StrVecToStringArray.  Just use it as a
function, and pass a vector of strings to it.  It will return a StringArray object.  You can
also create an object of this class if it needs to be used as a string array multiple times.
Here are examples:

// use StrVecToStringArray as a function (function object)
std::vector<std::string> myStringVec;
myStringVec.push_back("test1");
myStringVec.push_back("Test2");
myXAxis->setLabels(StrVecToStringArray(myStringVec));

// or, create a StrVecToStringArray object, and use it multiple times.
StrVecToStringArray strArraySubstitute(myStringVec);
myXAxis->setLabels(strArraySubstitute);
myYAxis->setLabels(strArraySubstitute);

// one caveat... you can't create a StringArray object from this, and use it.
// This is because after the StringArray has been created, the converter object has been
// destroyed along with the data that was allocated and  copied to the StringArray.

// DON'T DO THIS!!!
StringArray myStringArray = StrVecToStringArray(myStringVec)); // DON'T DO THIS
// this will crash because the char arrays in myStringArray have been deallocated
// by the destructor in StrVecToStringArray.
myXAxis->setLabels(myStringArray);


Here's the class....

StrVecToStringArray
{
public:
  StrVecToStringArray(const std::vector<std::string>& strVec) : stringVec(strVec)
  {
    stringArray = new const char*[strVec.size()];
    for (int i = 0; i < static_cast<int>(strVec.size()); ++i) {
      stringArray[i] = strVec[i].c_str();
    }
  }

  ~StrVecToStringArray() { delete[] stringArray; }

  // conversion operator
  operator StringArray ()
    { return StringArray(stringArray, static_cast<int>(stringVec.size())); }

private:
  const std::vector<std::string>& stringVec;
  const char** stringArray;
};

  Re: A little problem to dynamically set the const char* array of labels in c++
Posted by Peter Kwan on Apr-17-2009 16:40
Hi Mitch,

Thanks a lot for sharing your inline class in this forum. It is very convenient. As dynamic memory allocation of an array of strings is a very common requirement in C++, I am sure your inline class will help a lot of people.

Regards
Peter Kwan

  Re: A little problem to dynamically set the const char* array of labels in c++
Posted by Mitch Haas on Apr-17-2009 17:32
No problem, Peter.

One note, I forgot the 'class' keyword in the class definition above.
So, I'll repeat the class definition here in it's entirety.

Thanks for this awesome library and the great support!  Not only does ChartDirector
product the best charts available, it has a very rich API that's very well thought out.
The documentation is also very complete.

Mitch




class StrVecToStringArray
{
public:
  StrVecToStringArray(const std::vector<std::string>& strVec) : stringVec(strVec)
  {
    stringArray = new const char*[strVec.size()];
    for (int i = 0; i < static_cast<int>(strVec.size()); ++i) {
      stringArray[i] = strVec[i].c_str();
    }
  }

  ~StrVecToStringArray() { delete[] stringArray; }

  // conversion operator
  operator StringArray ()
    { return StringArray(stringArray, static_cast<int>(stringVec.size())); }

private:
  const std::vector<std::string>& stringVec;
  const char** stringArray;
};

  Re: A little problem to dynamically set the const char* array of labels in c++
Posted by Joao Marcos M. Mercado on Oct-18-2016 08:48
Thank you very much..