我正在尝试编写一个解析命令行参数的函数。这是函数声明:
void parse(int, char const **);
为了以防万一,我还尝试使用(const char)**
const char **
,cchar **
和typedef const char cchar
。但是,如果我将char **
传递给函数,所有这些(如预期的那样,因为它们应该全部相同)会导致错误,如:
void main(int argc, char **argv) {
parse(argc, argv);
我从GNU的编译器得到的错误是error: invalid conversion from 'char**' to 'const char**'
,来自Clang的错误是candidate function not viable: no known conversion from 'char **' to 'const char **' for 2nd argument
。
我已经看到这样的解决方案被建议为声明指向char(const char * const *
)的const指针,但我不希望任何指针都是const因为我希望能够修改指针所以我可以使用for(; **argv; ++*argv)
迭代参数。如何声明“指向const char的非const指针的非常量指针”?
答案 0 :(得分:7)
该函数应声明为:
void parse(int, char const * const *);
在C ++中,char **
可以在所有指针深度隐式添加const
,因此您可以将其称为parse(argc, argv)
。
在C中,const
只能在第一个指针深度添加(这是语言中的设计缺陷)。 Here is a dedicated thread。因此,您不得不将该函数称为:parse(argc, (char const * const *)argv);
。
答案 1 :(得分:5)
最安全的签名阻止修改参数,同时允许任何其他const
组合调用该函数:
parse(int argc, char const* const* argv);
这意味着argv
是指向const
指针的指针 指向const char
您可以愉快地迭代这样的参数:
for(auto arg = argv + 1; *arg; ++arg)
{
if(!std::strcmp(*arg, "--help"))
return print_help();
else if(!std::strcmp(*arg, "-v") || !std::strcmp(*arg, "--verbose"))
verbose_flag = true;
// ... etc...
}
请注意,不需要接受变量int argc
,因为字符数组数组 null terminate 。
所以我通常使用它:
struct config
{
// program options and switches
};
config parse_commandline(char const* const* argv);