Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a vector of strings to execv

Tags:

c++

string

vector

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?

like image 487
node ninja Avatar asked Apr 26 '11 23:04

node ninja


People also ask

How do you convert a string to a vector?

To add string data to string vector you need write push_back(s), where s is string.

Can vector store strings?

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.

How do I remove a string from a vector file?

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 !=


3 Answers

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);
like image 117
wallyk Avatar answered Sep 23 '22 04:09

wallyk


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.

like image 2
QuantumMechanic Avatar answered Sep 22 '22 04:09

QuantumMechanic


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 newed 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.

like image 2
kiw Avatar answered Sep 22 '22 04:09

kiw