Convert Vector<String> into Char** C++

convert vector string into char** C++

It is possible to solve the problem without copying out all the std::strings as long as the function does not modify the passed in char**. Otherwise I can see no alternative but to copy out everything into a new char**` structure (see second example).

void old_func(char** carray, size_t size)
{
for(size_t i = 0; i < size; ++i)
std::cout << carray[i] << '\n';
}

int main()
{
std::vector<std::string> strings {"one", "two", "three"};
std::vector<char*> cstrings;
cstrings.reserve(strings.size());

for(size_t i = 0; i < strings.size(); ++i)
cstrings.push_back(const_cast<char*>(strings[i].c_str()));

// Do not change any of the strings here as that will
// invalidate the new data structure that relies on
// the returned values from `c_str()`
//
// This is not an issue after C++11 as long as you don't
// increase the length of a string (as that may cause reallocation)

if(!cstrings.empty())
old_func(&cstrings[0], cstrings.size());
}

EXAMPLE 2: If the function must modify the passed in data:

void old_func(char** carray, size_t size)
{
for(size_t i = 0; i < size; ++i)
std::cout << carray[i] << '\n';
}

int main()
{
{
// pre C++11
std::vector<std::string> strings {"one", "two", "three"};

// guarantee contiguous, null terminated strings
std::vector<std::vector<char>> vstrings;

// pointers to rhose strings
std::vector<char*> cstrings;

vstrings.reserve(strings.size());
cstrings.reserve(strings.size());

for(size_t i = 0; i < strings.size(); ++i)
{
vstrings.emplace_back(strings[i].begin(), strings[i].end());
vstrings.back().push_back('\0');
cstrings.push_back(vstrings.back().data());
}

old_func(cstrings.data(), cstrings.size());
}

{
// post C++11
std::vector<std::string> strings {"one", "two", "three"};

std::vector<char*> cstrings;
cstrings.reserve(strings.size());

for(auto& s: strings)
cstrings.push_back(&s[0]);

old_func(cstrings.data(), cstrings.size());
}
}

NOTE: Revised to provide better code.

How can I convert vector string to char* arr[]?

When you use memcpy, arr[i] is not guaranteed to be a null-terminated string. To treat arr[i] as null terminated string, as in

cout << arr[i] << endl;

causes undefined behavior.


You need couple of minor changes.

  1. Allocate one more byte of memory.
  2. Use strcpy instead of memcpy.
arr[i] = new char[vv[i].size() + 1];
strcpy(arr[i], vv[i].c_str());

Convert vector string to char** for use in execvp

I found that the answer lies with adding the NULL terminator to the end of the vector so that execvp knows where to end pvec.data(); This is thanks to Fatih above.

  std::vector<char*> pvec(tokens.size());
std::transform(tokens.begin(), tokens.end(), pvec.begin(), [](auto& str) {
return &str[0];
});
pvec.push_back(NULL);
pvec.data();

pid = fork();
// if we enter child process
if (pid == 0)
{
if (execvp(pvec.data()[0], pvec.data()) == -1)
{
printf("right here officer\n");
}
exit(EXIT_FAILURE);
}```

How to convert a vector string to a vector char*

A faster way of doing this is

std::vector<const char*> charVec(strVec.size(),nullptr);
for (int i=0; i<strVec.size();i++) {
charVec[i]= strVec[i].c_str();
}

and then using the resulting vector. This will save a lot of time on memory allocation for large sets of data.

Convert string vector to char array in c++

Reading the manual reveals that "execvp provides an array of pointers to null-terminated strings". So you need to create such an array. Here's one way:

std::vector<char *> argv(strings.size() + 1);    // one extra for the null

for (std::size_t i = 0; i != strings.size(); ++i)
{
argv[i] = &strings[i][0];
}

execvp(argv[0], argv.data());

How to convert std::vector std::string to const char* array ?

You can't convert it, but it's straightforward to create an array:

std::vector<const char*> strings;
for (int i = 0; i < list.size(); ++i)
strings.push_back(list[i].c_str();

And now, strings.data() gives you an array of const char*.

Note that strings should not be used after list has been destroyed, since it holds pointers to data that lives in list. I'd probably wrap this in a function:

void call_C_function(const std::vector<std::string>& list) {
std::vector<const char*> strings;
for (int i = 0; i < list.size(); ++i)
strings.push_back(list[i].c_str());
c_function(strings.data());
}

That way, strings will live only through the call to c_function, and there is no danger of it outlasting list.

How to convert vector vector string to char **

You can iterate over first vector and then

vector<string> tokens;
char* args;
args = new char [tokens.size()];
copy( tokens.begin(), tokens.end(), args);


Related Topics



Leave a reply



Submit