在满足execvp的第二个参数方面遇到很多麻烦。编译器说它需要一个char * const *传递给我有一个const char **。我希望它来自用户输入:
std::string x;
std::cout<<" [CMD]: ";
getline(std::cin, x);
const char** args = fillArgs(x);
execvp(args[0], args);
fillArgs的代码是将字符串转换为动态分配的指向字符数组的指针。简而言之,它看起来像这样:
const char** fillArgs(std::string currentCMD)
{
//Above this, the string passed into the function is split into substrings separated
//by whitespaces and each is placed into the string vector called input.
const char** command = new const char*[SIZE];
for(int i = 0; i < SIZE; i++)
{
command[i] = input[i].c_str();
}
return command;
}
我知道它需要以nullpointer结束并在上面的代码中处理它。建议?
答案 0 :(得分:2)
char* const argv[]
(和char* const *argv
)是指向可变const
数组的char
指针数组。 (即使execvp
可能不会修改字符串)。
但是const char** args
(与char const** args
相同)是一组指向const char
数组的可变指针。
std::string::c_str
返回指向const char*
数组的const char
指针。但是execvp
需要可变的char
数组。
一种解决方案是使用const_cast
:
const char* command = input[i].c_str();
char* command_mutable = const_cast<char*>(command);
char* const *argv;
argv[i] = command_mutable;
这适用于execvp
,因为它只读取字符串并复制它们以供新的可执行文件使用,并且不会返回。对于可以修改字符串并正常返回的函数,它是未定义的行为。
但另一个问题是c_str
返回的指针只有std::string
对象存在才有效。函数fillArgs
不正确,因为当它返回返回值中的指针时无效。 (如果它是在堆栈上分配的话,也是command
数组本身。)
所以这会奏效:
std::string str = "example";
char* const args[3];
args[1] = const_cast<char*>(str.c_str());
args[2] = nullptr;
execvp(args[0], args);
// Not the other program is running
当使用可以修改数组的execvp
以外的其他函数时,最好为函数创建一个临时数组:
std::string str = "example";
std::unique_ptr<char[]> tmp_str(new char[str.size() + 1]);
std::memcpy(tmp_str.get(), str.c_str(), str.size() + 1);
char* const args[3];
args[1] = tmp_str.get();
args[2] = nullptr;
something(args[0], args);
tmp_str.reset(); // release the temporary memory
答案 1 :(得分:0)
好吧,在execvp not working when converting from vector<string> to vector<char*> to char**引起我的注意后,我又回到了使用那个字符串向量。这种方式更有效,更容易阅读我的代码。我错过了.data()函数。