我正在做一个学校作业,我必须调用execvp,其方法签名如下
execvp(const char* file, char* const argv[])
但我的数据格式如下:
std::vector<std::string*>
我一直试图将所述矢量转换为第二种格式execvp()
的正确格式,但不可避免地会出现以下错误:
command.cc:120:29: error: invalid conversion from ‘const char**’ to ‘char* const*’ [-fpermissive]
execvp(args[0], argv);
我尝试了不同的变体,但它们都导致了这个错误。这个错误让我很困惑,因为我不知道const*
是什么意思。你怎么能有const*
?我考虑将std::vector
更改为其他类型,但这是一项任务,我实际上不允许更改它。下面是我用来尝试从向量中创建char*[]
的代码:
const size_t numArgs = _simpleCommands[i]->_arguments.size();
std::vector<const char*> args;
for(size_t j = 0; j < numArgs; ++j)
{
args.push_back(strPtrToCharPtr(_simpleCommands[i]->_arguments[i]));
}
const char** argv = new const char*[numArgs];
for(size_t j = 0; j < numArgs; ++j)
{
argv[j] = args[j];
}
execvp(args[0], argv);
答案 0 :(得分:2)
我不理解std::vector<std::string *>
部分(你确定你不需要std::vector<std::string>
吗?),无论如何......
const
的规则:它适用于左边的元素;如果左侧有非元素,则将其应用于右侧的元素。
所以const char**
(或char const **
,如果您愿意)是指向常量char
的指针。我的意思是:常量部分是char
指向的,而不是指针。
而char * const *
是指向char
的常量指针的指针;在这种情况下,常量部分是两个指针之一,而不是char
指向的。
在你的情况下功能
execvp(const char* file, char* const argv[])
期望作为第二个参数,char * const argv[]
(一个C型样式的常量指针数组char
),您可以看作char * const *
。
但你打电话
execvp(args[0], argv);
其中argv
是char const **
,与char * const *
不同。
所以错误:函数期望能够修改指向的char
并且你传递一个指向不可修改char
的指针
您无法将argv
定义为char * const *
char * cont * argv = new char * const [numArgs]; // <-- WRONG
因为你无法修改它。
所以,为了解决这个问题,我想你可以将argv
定义为char **
char** argv = new char* [numArgs];
for(size_t j = 0; j < numArgs; ++j)
argv[j] = args[j];
execvp(args[0], argv);
如果将非常量对象传递给需要常量对象的函数(相反可能有问题),则没有问题,因此您可以将char **
传递给期望{的函数{1}}。
答案 1 :(得分:1)
course_number = ['2920', '3100', '3200', '3300', '3500', '4100', '4200', '4300', '4310', '4400', '4500']
for doc in db.all_classes.find(
{"class_schedule.subject_code": "CSCI" },
{ "class_schedule.course_number": { '$elemMatch': { course_number } } } ):
print doc
原型意味着char* const argv[]
是指向argv
的指针数组(的地址),无法修改数组中的指针 ,但他们指向的字符串可以。这与char
不同,char const **
是指向char
指针的指针,其中<{1}} 的字符无法修改。由于将其传递给可能修改数组中字符串的函数会违反const
const char **
限定符,因此不允许这样做。 (你可以用const_cast
来做,但这将解决错误的问题。)
由于execvp()
是一个非常古老的UNIX函数,并且今天没有相同的接口,因此它没有任何参数来告诉操作系统有多少参数,也没有保证不修改内容数组中的字符串。您可以通过将最终元素设置为NULL
来终止数组。
它与argv
的{{1}}参数的格式类似。实际上,如果它是用C语言编写的,它就会成为你运行的程序的main()
函数的argv
参数。
这不是一个完整的解决方案,因为这是一个家庭作业,你想自己解决它,但你必须自己创建该阵列。您可以通过创建main()
来设置std::vector<char *> argv( args.size() + 1 )
,将最后一个元素设置为来自.data()
的相应元素的args
指针,并将最后一个元素设置为NULL
。然后,将argv.data()
传递给execvp()
。
请注意the POSIX.1-2008 standard说,
argv[]
和envp[]
指针数组以及这些数组指向的字符串不应通过调用其中一个exec函数来修改,除非替换过程映像。
因此,如果你不介意生活危险,那么你应该能够摆脱阵列中弦乐的const
- 这一次。通常,您需要为数组中的每个常量字符串创建一个可修改的副本。
答案 2 :(得分:1)
1)您不需要const *
(const指针),因为如果需要,指针会自动转换为const指针;
2)但是你需要提供char*
(不是const char*
!)数组作为execvp的第二个参数,即你的字符串字符应该是可修改的。通过拥有这样的签名,execvp保留修改提供的参数字符串的权利(是的,这似乎很奇怪 - 但是进程确实有权更改其参数 - 请注意main()
例程可能有(非const){{ 1}}参数!)。因此,您需要在代码段中删除char** argv
并将其替换为const char*