Geongu Aiden Park
Geongu Aiden Park

Reputation: 71

execvp() using vector<string *>

_arguments = std::vector<std::string *>();

I have above vector declared and I want to use it for execvp()

int execvp(const char *file, char *const argv[]);

How do I convert the type to fit into this function?

It should be something like this

execvp(_arguments[0], _arguments)

Upvotes: 1

Views: 1838

Answers (3)

Miles Budnek
Miles Budnek

Reputation: 30579

You can't use it directly. You'll need to copy pointers to each string's internal buffer into another vector.

Assuming arguments_ is initialized like this:

std::vector<std::string*> arguments_ = {
    new std::string("mycmd"),
    new std::string("arg1"),
    new std::string("arg2")
}

You can call execvp something like this:

// execvp needs a NULL terminator, so make argv one element longer
// than arguments_
std::vector<char*> argv(arguments_.size() + 1);

// copy pointers to each string's buffer into the new vector
std::transform(arguments_.begin(), arguments_.end(), argv.begin(),
               [](std::string* arg) {
                   return arg->data();
               });

// The last element of argv was implicitly initialized to a null pointer
// so this isn't actually necessary.
// I just included it to be explicit
argv.back() = nullptr;

// pass a pointer to the array of char*s to execvp
execvp(argv[0], argv.data());

Note that this example relies on the non-const qualified overload of std::string::data added in C++17. Use &(*arg)[0] instead if you're using an older revision of the C++ standard.

Upvotes: 2

10366809
10366809

Reputation: 1

_arguments = std::vector<std::string *>();

The standard string class manages its internal data as char array. To access the internal data, call the method data(). The return type is const char*.

By the way, the pointer type for std::string is not necessary.

Also have a look on the reference: http://www.cplusplus.com/reference/string/string/data/

Upvotes: -1

comingstorm
comingstorm

Reputation: 26117

You will need to create a new array of pointers to the strings' data, instead of to the std::strings themselves. There are many ways to do this, but one simple way is to use another std::vector and a structured for loop:

assert(_arguments.size() > 0);  // else the executable will be invalid

std::vector<const char *> args;
args.reserve(_arguments.size() + 1);
for(string *sp: _arguments) {
  args.push_back(sp->c_str());
}
args.push_back(nullptr);  // needed to terminate the args list

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

Upvotes: 2

Related Questions