I have found that the easiest way to build my program argument list is as a vector of strings. However, execv expects an array of chars for the second argument. What's the easiest way to get it to accept of vector of strings?
To add string data to string vector you need write push_back(s), where s is string.
Use a vector for array-like storage of your strings. Example 4-6 offers a simple example. vector s follow array semantics for random access (they also do a lot more), so they are easy and familiar to use. vector s are just one of many sequences in the standard library, however; read on for more of this broad subject.
To remove a single copy of an element from a std::vector , you can use std::find and the std::vector 's erase member function like this: auto itr = std::find(v. begin(), v. end(), rnames); if (itr !=
execv()
accepts only an array of string pointers. There is no way to get it to accept anything else. It is a standard interface, callable from every hosted language, not just C++.
I have tested compiling this:
std::vector<string> vector;
const char *programname = "abc";
const char **argv = new const char* [vector.size()+2]; // extra room for program name and sentinel
argv [0] = programname; // by convention, argv[0] is program name
for (int j = 0; j < vector.size()+1; ++j) // copy args
argv [j+1] = vector[j] .c_str();
argv [vector.size()+1] = NULL; // end of arguments sentinel is NULL
execv (programname, (char **)argv);
The prototype for execv
is:
int execv(const char *path, char *const argv[]);
That means the argument list is an array of pointers to null-terminated c strings.
You have vector<string>
. Find out the size of that vector and make an array of pointers to char. Then loop through the vector and for each string
in the vector set the corresponding element of the array to point to it.
I stumbled over the same problem a while ago.
I ended up building the argument list in a std::basic_string<char const*>
. Then I called the c_str()
method and did a const_cast<char* const*>
on the result to obtain the list in a format that execv
accepts.
For composed arguments, I new
ed strings (ordinary strings made of ordinary chars ;) ), took their c_str()
and let them leak.
The const_cast
is necessary to remove an additional const
as the c_str()
method of the given string type returns a char const* const*
iirc. Typing this, I think I could have used std::basic_string<char*>
but I guess I had a reason...
I am well aware that the const
-casting and memory leaking looks a bit rude and is indeed bad practise, but since execv
replaces the whole process it won't matter anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With