I have a vector of strings vector<string> args
that I need to convert to a c string to in turn run as arguments through an execvp call. I keep getting the error "invalid conversion from const char* to char* for the line in my loop. I don't understand how to fix this while still resulting in something I can feed to execvp. While I have seen similar posts, none of the solutions I have come across seem to fix my issue.
int argsLen = c->args.size();
char **argv = new char* [c->args.size() + 1];
for (int index = 0; index < c->args.size(); ++index)
argv[index] = c->args[index].c_str();//note that c is the structure in which args is contained
argv[c->args.size() + 1] = NULL;
//execvp(argv[0], argv);
If you want to do this with no chance of leaking memory or memory overwrite, you can do the following:
typedef std::vector<char> CharArray;
typedef std::vector<CharArray> ArgumentVector;
//...
ArgumentVector argVec;
std::vector<char *>argv;
for (int index = 0; index < c->args.size(); ++index)
{
// get the command and create copy
argVec.push_back(CharArray(c->args[index].begin(), c->args[index].end()));
// get pointer to newly created entity and place in argv vector
argV.push_back(argVec.back().data());
}
// the last argument is NULL
argV.push_back(NULL);
execvp(argV[0], // the first item in the array
argV.data(), // the char** we are sending
All we did was create a std::vector<char*>
, and the way we set the pointers in this vector is to point to data from another vector. Once the std::vector<char*>
is populated, then char**
is just a pointer to the first item.
BTW, this is one of the legitimate reasons to use a vector<char *>
as opposed to a vector<string>
. In most other cases, if you want a vector of strings, you use vector<string>
.
c_str()
returns a const char pointer to its internal buffer, whose contents you are not allowed to change (thats why its const) and obviously cannot assign to your char buffer. You need to allocate memory for each string, and copy it:
argv[index] = new char[c->args[index].length()];
strcpy(argv[index], c->args[index].c_str());
include cstring
header for strcpy.
Maybe this can help:
char const **argv = new const char* [c->args.size() + 1];