如何将字符串向量传递给execv

时间:2011-04-26 23:55:01

标签: c++ string vector

我发现构建程序参数列表的最简单方法是作为字符串向量。但是,execv期望第二个参数的字符数组。让它接受字符串向量的最简单方法是什么?

5 个答案:

答案 0 :(得分:13)

execv()只接受一个字符串指针数组。没有办法让它接受任何其他东西。它是一个标准接口,可以从每种托管语言调用,而不仅仅是C ++。

我已经测试了这个:

    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);

答案 1 :(得分:2)

execv的原型是:

int execv(const char *path, char *const argv[]);

这意味着参数列表是一个指向以null结尾的c字符串的指针数组。

你有vector<string>。找出该向量的大小,并创建一个指向char的指针数组。然后循环遍历向量,并为向量中的每个string设置数组的相应元素以指向它。

答案 2 :(得分:1)

你不能改变execv的工作方式(不管怎么说都不容易),但你可以用你想要的方式重载函数名称:

int execv(const string& path, const vector<string>& argv) {
    vector<const char*> av;
    for (const string& a : argv) {
        av.push_back(a.c_str());
    av.push_back(0);
    return execv(path.c_str(), &av[0]);
}

当然,这可能会引起一些混乱。除了execv()之外,你最好给它一个名字。

注意:我只是把它打成了我的头顶。它可能无法正常工作。它甚至可能无法编译; - )

答案 3 :(得分:1)

我刚才偶然发现了同样的问题。

我最终在std::basic_string<char const*>中构建了参数列表。然后我调用了c_str()方法并对结果执行了const_cast<char* const*>,以execv接受的格式获取列表。

对于复合参数,我new ed字符串(由普通字符组成的普通字符串;)),取出c_str()并让它们泄漏。

由于给定字符串类型的const_cast方法返回const iirc,因此删除其他c_str()时需要char const* const*。输入这个,我想我可以使用std::basic_string<char*>,但我想我有理由......


我很清楚const - 投射和内存泄漏看起来有点粗鲁,确实是不好的做法,但是因为execv取代整个过程无论如何都无关紧要。

答案 4 :(得分:1)

是的,通过利用矢量使用的内部数组,它可以非常干净地完成。最好不要在向量中使用C ++字符串,并且const_cast字符串文字和string.c_str()用于char *。

这样可行,因为标准保证其元素是连续存储的(参见https://stackoverflow.com/a/2923290/383983

#include <vector>

using std::vector;

int main() {
  vector<char*> commandVector;

  // do a push_back for the command, then each of the arguments
  commandVector.push_back(const_cast<char*>("echo"));
  commandVector.push_back(const_cast<char*>("testing"));
  commandVector.push_back(const_cast<char*>("1"));
  commandVector.push_back(const_cast<char*>("2"));
  commandVector.push_back(const_cast<char*>("3"));

  // push NULL to the end of the vector (execvp expects NULL as last element)
  commandVector.push_back(NULL);

  const int status = execvp(command[0], &command[0]);
  return 0;
}

执行const_cast以避免“已弃用从字符串常量转换为'char *'”。字符串文字在C ++中实现为'const char *'。 const_cast是这里最安全的转换形式,因为它只删除了const而且没有做任何其他有趣的事情。 execvp无论如何都不会编辑这些值。

如果你想避免所有强制转换,你必须通过将所有值复制到'char *'类型来使这段代码复杂化。

虽然如果知道要传递给execv / execl的参数个数,但在C中写这个更容易。