Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从矢量转换时execvp不工作<;字符串>;到向量<;字符*>;烧焦**_C++_Vector_Execvp - Fatal编程技术网

C++ 从矢量转换时execvp不工作<;字符串>;到向量<;字符*>;烧焦**

C++ 从矢量转换时execvp不工作<;字符串>;到向量<;字符*>;烧焦**,c++,vector,execvp,C++,Vector,Execvp,从字符串向量到char*向量再到char**,当参数以char**的形式输入时是有效的,但是转换似乎有问题,我无法找到区别 有更好的方法吗 vector<string> args; /* code that correctly parses args from user input */ pid_t kidpid = fork(); if (kidpid < 0) { perror("Internal error: c

从字符串向量到char*向量再到char**,当参数以char**的形式输入时是有效的,但是转换似乎有问题,我无法找到区别

有更好的方法吗

    vector<string> args;

    /* code that correctly parses args from user input */

    pid_t kidpid = fork();
    if (kidpid < 0)
    {
        perror("Internal error: cannot fork.");
        return -1;
    }
    else if (kidpid == 0)
    {
        // I am the child.

        vector<char*>argcs;
        for(int i=1;i<args.size();i++)
        {
            char * temp = new char[args.at(i).length()];
            for(int k=0;k<args.at(i).length();k++)
            {
                temp[k] = args.at(i).at(k);
            }
            argcs.push_back(temp);
        }

        char** argv = new char*[argcs.size() + 1];
        for (int i = 0; i < argcs.size(); i++)
        {
            argv[i] = argcs[i];
        }
        argv[args.size()] = NULL;

        execvp(program, args);

        return -1;
    }
向量args;
/*从用户输入正确解析参数的代码*/
pid_t kidpid=fork();
if(kidpid<0)
{
perror(“内部错误:无法分叉”);
返回-1;
}
否则如果(kidpid==0)
{
//我是孩子。
向量机;

对于(inti=1;i首先,如果下一步要做的是调用
execvp
,那么复制
std::string
s就没有意义了

如果
execvp
成功,那么它将永远不会返回,整个内存映像将消失在烟雾中(或者更准确地说,被一个全新的映像替换)。在构建新映像的过程中,
exec*
将复制argv数组(和环境数组)在任何情况下,都不会调用
std::vector
std::string
析构函数

另一方面,如果
execvp
失败,则传递给它的参数将不会被修改。(Posix:
argv[]
envp[]
指针数组和这些数组所指向的字符串不得通过调用某个exec函数进行修改,除非作为替换进程映像的结果。”)

在这两种情况下,都不需要复制字符串。您可以使用
std::string::c_str()
提取指向底层c字符串的指针(作为
const char*
,但请参见下文)

其次,如果您使用的是C++11或更新版本,
std::vector
附带了一个
data()
成员函数,该函数返回指向底层存储的指针。因此,如果您有
std::vector svec
,那么
svec.data()
将是底层
char*[]
,这是您要传递到
execvp
中的内容

因此,问题归结为从
std::vector
创建
std::vector
,这很简单:

else if (kidpid == 0) {
    // I am the child.
    std::vector<char*> argc;
    // const_cast is needed because execvp prototype wants an
    // array of char*, not const char*.
    for (auto const& a : args)
        argc.emplace_back(const_cast<char*>(a.c_str()));
    // NULL terminate
    argc.push_back(nullptr);
    // The first argument to execvp should be the same as the
    // first element in argc, but we'll assume the caller knew
    // what they were doing, and that program is a std::string. 
    execvp(program.c_str(), argc.data());
    // It's not clear to me what is returning here, but
    // if it is main(), you should return a small positive value
    // to indicate an error
    return 1;
}
else如果(kidpid==0){
//我是孩子。
std::载体argc;
//需要const_cast,因为execvp原型需要
//字符*的数组,而不是常量字符*。
用于(自动常量&a:args)
argc.emplace_back(const_cast(a.c_str()));
//空终止
argc.推回(nullptr);
//execvp的第一个参数应与
//argc中的第一个元素,但我们假设调用方知道
//他们在做什么,这个程序是一个std::字符串。
execvp(program.c_str(),argc.data());
//我不清楚什么会回到这里,但是
//如果是main(),则应返回一个小的正值
//指出错误
返回1;
}

首先,如果下一步要做的是调用
execvp
,那么复制
std::string
就没有意义了

如果
execvp
成功,那么它将永远不会返回,整个内存映像将消失在烟雾中(或者更准确地说,被一个全新的映像替换)。在构建新映像的过程中,
exec*
将复制argv数组(和环境数组)在任何情况下,都不会调用
std::vector
std::string
析构函数

另一方面,如果
execvp
失败,则传递给它的参数将不会被修改。(Posix:
argv[]
envp[]
指针数组和这些数组所指向的字符串不得通过调用某个exec函数进行修改,除非作为替换进程映像的结果。”)

在这两种情况下,都不需要复制字符串。您可以使用
std::string::c_str()
提取指向底层c字符串的指针(作为
const char*
,但请参见下文)

其次,如果您使用的是C++11或更新版本,
std::vector
附带了一个
data()
成员函数,该函数返回指向底层存储的指针。因此,如果您有
std::vector svec
,那么
svec.data()
将是底层
char*[]
,这是您要传递到
execvp
中的内容

因此,问题归结为从
std::vector
创建
std::vector
,这很简单:

else if (kidpid == 0) {
    // I am the child.
    std::vector<char*> argc;
    // const_cast is needed because execvp prototype wants an
    // array of char*, not const char*.
    for (auto const& a : args)
        argc.emplace_back(const_cast<char*>(a.c_str()));
    // NULL terminate
    argc.push_back(nullptr);
    // The first argument to execvp should be the same as the
    // first element in argc, but we'll assume the caller knew
    // what they were doing, and that program is a std::string. 
    execvp(program.c_str(), argc.data());
    // It's not clear to me what is returning here, but
    // if it is main(), you should return a small positive value
    // to indicate an error
    return 1;
}
else如果(kidpid==0){
//我是孩子。
std::载体argc;
//需要const_cast,因为execvp原型需要
//字符*的数组,而不是常量字符*。
用于(自动常量&a:args)
argc.emplace_back(const_cast(a.c_str()));
//空终止
argc.推回(nullptr);
//execvp的第一个参数应与
//argc中的第一个元素,但我们假设调用方知道
//他们在做什么,这个程序是一个std::字符串。
execvp(program.c_str(),argc.data());
//我不清楚什么会回到这里,但是
//如果是main(),则应返回一个小的正值
//指出错误
返回1;
}

让我们了解问题所在可能会有所帮助。抱歉,用户,execvp找不到匹配的构造函数或让我们了解问题所在可能会有所帮助。抱歉,用户,execvp找不到匹配的构造函数有一个
std::vector argc
,无需常量转换。@n.m:那么argc.data是
const char*[]
这不是执行VP的正确原型(TIAS:“错误:从'const char**'到'char*const*'[-fppermissive]]的转换无效)嗯,是的。我的印象是execvp的参数是
const char*const*
。但是不,这个原型在C语言中不太好用。太糟糕了!太迷人了…我缺少的工具是.d