std::vector<std::string> to char* array

Christopher DuBois picture Christopher DuBois · Aug 13, 2011 · Viewed 49.4k times · Source

I have a std::vector<std::string> that I need to use for a C function's argument that reads char* foo. I have seen how to convert a std::string to char*. As a newcomer to C++, I'm trying to piece together how to perform this conversion on each element of the vector and produce the char* array.

I've seen several closely related SO questions, but most appear to illustrate ways to go the other direction and create std::vector<std::string>.

Answer

Nawaz picture Nawaz · Aug 13, 2011

You can use std::transform as:

std::transform(vs.begin(), vs.end(), std::back_inserter(vc), convert);  

Which requires you to implement convert() as:

char *convert(const std::string & s)
{
   char *pc = new char[s.size()+1];
   std::strcpy(pc, s.c_str());
   return pc; 
}

Test code:

int main() {
       std::vector<std::string>  vs;
       vs.push_back("std::string");
       vs.push_back("std::vector<std::string>");
       vs.push_back("char*");
       vs.push_back("std::vector<char*>");
       std::vector<char*>  vc;

       std::transform(vs.begin(), vs.end(), std::back_inserter(vc), convert);   

       for ( size_t i = 0 ; i < vc.size() ; i++ )
            std::cout << vc[i] << std::endl;

       for ( size_t i = 0 ; i < vc.size() ; i++ )
            delete [] vc[i];
}

Output:

std::string
std::vector<std::string>
char*
std::vector<char*>

Online demo : http://ideone.com/U6QZ5

You can use &vc[0] wherever you need char**.

Note that since we're using new to allocate memory for each std::string (in convert function), we've to deallocate the memory at the end. This gives you flexibility to change the vector vs; you can push_back more strings to it, delete the existing one from vs, and vc (i.e vector<char*> will still be valid!

But if you don't want this flexibility, then you can use this convert function:

const char *convert(const std::string & s)
{
   return s.c_str();
}

And you've to change std::vector<char*> to std::vector<const char*>.

Now after the transformation, if you change vs by inserting new strings, or by deleting the old ones from it, then all the char* in vc might become invalid. That is one important point. Another important point is that, you don't need to use delete vc[i] in your code anymore.