By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,820 Members | 1,189 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,820 IT Pros & Developers. It's quick & easy.

best way to copy a vector<string> to char**

P: n/a
What is the "best" way to copy a vector of strings to an array of
character strings? By "best", I mean most elegantly/tersely written,
but without any sacrifice in performance.

I'm writing an application using C++ and the STL for handling my data.
Unfortunately, I must interact with a (vanilla) C API. I use vectors of
strings (for simplicity and less memory hassle), but the function calls
for this API require arrays of character strings (char**).

Below is some code to copy a vector of strings to an array of character
strings. It works (based on minimal testing anyway :). I'm just
curious if there is a "better" way to do it.

Thanks,
Matt
email at: http://raw-sewage.net/index.php?file=email
// this code is public domain
// compiles with the GNU C++ compiler (g++) v3.2.3

#include <string>
#include <vector>
#include <iostream>
#include <cstring>

using namespace std;

int main(int argc, char** argv)
{
// handy typedefs just to save some typing
typedef std::vector<std::string> strvec_t;
typedef std::vector<std::string>::iterator strveciter_t;

strvec_t strvec;

// fill the string vector with some sample strings
strvec.push_back("Hello"); strvec.push_back(", ");
strvec.push_back("world"); strvec.push_back("... ");
strvec.push_back("How "); strvec.push_back("are ");
strvec.push_back("you "); strvec.push_back("today");
strvec.push_back("?");

// print out the strings (just for sanity)
for (strveciter_t ii=strvec.begin(); ii!=strvec.end(); ++ii)
cout << *ii;
cout << endl;

// allocate memory for an array of character strings
char** cstr = new char*[strvec.size()];

// for each string, allocate memory in the character array and copy
for (unsigned long i=0; i<strvec.size(); i++) {
cstr[i] = new char[strvec[i].size()+1];
strncpy(cstr[i], strvec[i].c_str(), strvec[i].size());
}

// print out the newly copied strings
for (unsigned long i=0; i<strvec.size(); i++) cout << cstr[i];
cout << endl;

// free dynamic memory
for (unsigned long i=0; i<strvec.size(); i++) delete[] cstr[i];
delete[] cstr;

return 0;
}

Jul 22 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a
Matt Garman wrote:
What is the "best" way to copy a vector of strings to an array of
character strings? By "best", I mean most elegantly/tersely written,
but without any sacrifice in performance.

I'm writing an application using C++ and the STL for handling my data.
Unfortunately, I must interact with a (vanilla) C API. I use vectors of
strings (for simplicity and less memory hassle), but the function calls
for this API require arrays of character strings (char**).

Below is some code to copy a vector of strings to an array of character
strings. It works (based on minimal testing anyway :). I'm just
curious if there is a "better" way to do it.


Here is another version with a helper class that does what you did but
in a little less.

This version does not allocate anything with new - instead it just uses
the c_str() value as the "char *" which I took the liberty to change to
const char *. Anyhow - if that does not work for you, there is nothing
stopping you from "new"ing whatever you want and deleting it in the
constuctor.

This is a (poor) demonstration of the "low threshold to create a new
class" rule.
// this code is public domain
// compiles with the GNU C++ compiler (g++) v3.2.3

#include <string>
#include <vector>
#include <iostream>
#include <cstring>

using namespace std;

class VectCharPP
{
public:

vector<const char*> ptrs;

VectCharPP( const vector< string > & v )
: ptrs( v.size() + 1 )
{
long i= v.size();

ptrs[ i ] = 0;

for ( --i ; i >= 0; --i ) {
ptrs[ i ] = v[ i ].c_str();
}
}

operator const char ** ()
{
return & ( ptrs[ 0 ] );
}

};
int main(int argc, char** argv)
{
// handy typedefs just to save some typing
typedef std::vector<std::string> strvec_t;
typedef std::vector<std::string>::iterator strveciter_t;

strvec_t strvec;

// fill the string vector with some sample strings
strvec.push_back("Hello"); strvec.push_back(", ");
strvec.push_back("world"); strvec.push_back("... ");
strvec.push_back("How "); strvec.push_back("are ");
strvec.push_back("you "); strvec.push_back("today");
strvec.push_back("?");

// print out the strings (just for sanity)
for (strveciter_t ii=strvec.begin(); ii!=strvec.end(); ++ii)
cout << *ii;
cout << endl;

// allocate new vector here.
VectCharPP cstr_v = strvec;

const char** cstr = cstr_v;

// NOTE THAT cstr only lives as long as the VectCharPP object ...
// since this is a legacy interface we assume this policy is easy
// easy to adhere to.

// print out the newly copied strings
for (unsigned long i=0; cstr[i]; i++) cout << cstr[i];
cout << endl;

return 0;
}

Jul 22 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.