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.
- Allocate one more byte of memory.
- Use
strcpy
instead ofmemcpy
.
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
How to Delete a Non-New Object
Are Parentheses Around the Result Significant in a Return Statement
Does the C++ Volatile Keyword Introduce a Memory Fence
Why Doesn't My Template Accept an Initializer List
Converting String of 1S and 0S into Binary Value
Construct Path for #Include Directive with MACro
How to Cout a Float Number with N Decimal Places
False Positive with Is_Copy_Constructible on Vector<Unique_Ptr>
How to Use Std::Sort with a Vector of Structures and Compare Function
Issuing System Commands in Linux from C, C++
Run an Application in Gdb Until an Exception Occurs
How to Get Current Timestamp in Milliseconds Since 1970 Just the Way Java Gets
C++ New Operator Thread Safety in Linux and Gcc 4
How Does the Custom Deleter of Std::Unique_Ptr Work
Operator< Comparing Multiple Fields
Why How to Not Brace Initialize a Struct Derived from Another Struct