C++ 玩getopt
嗨,我是一个非常新的编码和试图找到为什么这个getopt不工作。我的编译器抱怨i:o: 错误C2664“int getoptint,char**,char*”:无法将参数3从“const char[5]”转换为“char*”C++ 玩getopt,c++,getopt,C++,Getopt,嗨,我是一个非常新的编码和试图找到为什么这个getopt不工作。我的编译器抱怨i:o: 错误C2664“int getoptint,char**,char*”:无法将参数3从“const char[5]”转换为“char*” int main(int argc, char *argv[]) { int opt; while ((opt = getopt(argc, argv, "i:o:")) != -1) { switch (opt) {
int main(int argc, char *argv[])
{
int opt;
while ((opt = getopt(argc, argv, "i:o:")) != -1)
{
switch (opt)
{
case 'i':
printf("Input file: \"%s\"\n", optarg);
break;
case 'o':
printf("Output file: \"%s\"\n", optarg);
break;
}
}
return 0;
}
这很奇怪,因为当我阅读关于getopt的文章时,我看到选项参数是一个字符串,用于指定对该程序有效的选项字符。只需使用字符串指针:
char* opts = "i:o:";
getopt(argc, argv, opts);
根据错误消息,getopt函数需要一个可写的选项字符串。您可以通过如下方式创建一个非常量字符数组:
int main(int argc, char *argv[])
{
// non-const char array
char opts[] = "i:o:"; // copy a string literal in
int opt;
while ((opt = getopt(argc, argv, opts)) != -1)
{
switch (opt)
{
case 'i':
printf("Input file: \"%s\"\n", optarg);
break;
case 'o':
printf("Output file: \"%s\"\n", optarg);
break;
}
}
return 0;
}
您的原始代码在带有GCC v7的Linux上运行良好。您使用的版本的函数签名似乎不同
在我的系统上,它是:
int getopt (int argc, char** argv, const char* options);
但在您的系统上,它似乎是:
int getopt(int,char **,char *);
最后一个参数缺少const导致了错误,这就是为什么需要给它一个非const字符串
注意:我不建议为此使用const_cast,因为有些人可能会受到诱惑。你永远不知道函数是如何实现的,或者如果内部的实现可能在某个时间点发生变化。也不是合法的C++。OP是混合C和C++并发现其中的一些差异。第三个参数必须是可写的,字符串文字是不可写的。这可能是您正在使用的getopt库中的代码味道。您正在使用哪个运行时?我看到int getoptint argc,char*const argv[],const char*optstring;“我建议你放弃getopt。”弗雷德拉森试过了。没什么了不起的。我不知道Visual Studio库中有任何getopt函数-您使用了哪个头来获取它?如果getopt的实现真的没有修改选项字符串,您可能不用使用const_cast。但这类常量正确性错误表明库已过时或写得不好。由于getopt不会写入最后一个参数,因此可以常量转换字符串文字,而不是分配单独的非常量缓冲区:getoptargc、argv、,const_casti:o:。@Fredrarson不知道该函数是如何实现的,因此我永远不会基于概率和假设推荐const_cast。谁知道呢?也许它使用strtok?@Galik:我不知道这个实现是从哪里来的,因为它不是一个标准函数,而且OP也不在POSIX平台上。源代码可能是可用的。如果源不可用,您可以按照建议使用可修改的字符串,然后在调用后检查该字符串以查看是否已修改。不过,仍然存在一些风险。@fredrarson,但当您升级库时,实现可能会发生变化。所以我是在说不的阵营里