在C++中,如何仅将长选项与必需参数一起使用
In C++, how to use only long options with a required argument?
在C++程序中,我希望有一个带有必需参数的"只做长"选项。下面是我使用 getopt_long() 的最小示例,但它不起作用:
#include <getopt.h>
#include <cstdlib>
#include <iostream>
using namespace std;
void help (char ** argv)
{
cout << "`" << argv[0] << "` experiments with long options." << endl;
}
void parse_args (int argc, char ** argv, int & verbose, int & param)
{
int c = 0;
while (1)
{
static struct option long_options[] =
{
{"help", no_argument, 0, 'h'},
{"verbose", required_argument, 0, 'v'},
{"param", required_argument, 0, 0}
};
int option_index = 0;
c = getopt_long (argc, argv, "hv:",
long_options, &option_index);
cout << "c=" << c << endl;
if (c == -1)
break;
switch (c)
{
case 0:
if (long_options[option_index].flag != 0)
break;
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("n");
break;
case 'h':
help (argv);
exit (0);
case 'v':
verbose = atoi(optarg);
break;
case 'param':
param = atoi(optarg);
break;
case '?':
abort ();
default:
abort ();
}
}
}
int main (int argc, char ** argv)
{
int verbose = 0;
int param = 0;
parse_args (argc, argv, verbose, param);
cout << "verbose=" << verbose << " param=" << param << endl;
return EXIT_SUCCESS;
}
我用这个命令编译它(gcc 版本 4.1.2 20080704 Red Hat 4.1.2-46):
g++ -Wall test.cpp
它告诉我:
test.cpp:44:10: warning: character constant too long for its type
结果如下:
$ ./a.out -v 2 --param 3
c=118
c=0
option param with arg 3
c=-1
verbose=2 param=0
我试图让它在 ideone 上工作,但它甚至无法识别选项 -v
.
正如 trojanfoe 在对另一个问题的评论中所指出的,应该可以使用"只做长"选项,因为 GNU tar 可以这样做。但是,GNU tar 使用 argp,我很难理解它的源代码。
有人可以给我一个最小的例子,适用于 GNU getopt_long()
或 argp()
?
有两个问题:
-
根据示例代码(您的链接),结构中定义的最后一个选项必须
{0,0,0,0}
。我建议将定义更改为static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"verbose", required_argument, 0, 'v'}, {"param", required_argument, 0, 0}, {0,0,0,0} };
-
(更重要的是,)您必须包含实际处理"param"选项的代码。在
'0'
情况下执行此操作:case 0: if (long_options[option_index].flag != 0) break; if (strcmp(long_options[option_index].name,"param") == 0) param = atoi(optarg); break;
如您所见,我使用 strcmp
函数来比较字符串; 为此,您需要#include <cstring>
.顺便说一句,您还需要#include <cstdio>
才能使用printf
。
有了这些更改,该程序对我来说可以正常工作(在GCC 4.5.1上测试)。
在您的案例陈述中,您使用:
case 'param':
这会给你警告,因为编译器需要那个地方有一个字符。
事实上,我意识到当c
具有值时,我应该检查option_index
的值 0
,就像这样。这种情况在 GNU libc 示例中没有,所以这里是:
switch (c)
{
case 0:
if (long_options[option_index].flag != 0)
break;
if (option_index == 2)
{
param = atoi(optarg);
break;
}
case 'h':
help (argv);
exit (0);
case 'v':
verbose = atoi(optarg);
break;
case '?':
abort ();
default:
abort ();
}
另一种解决方案是使用结构选项中定义的"标志"成员值。
设置您的选项,如下所示:
int param_flag = 0;
{"param", required_argument, ¶m_flag, 1}
然后;
case 0:
if (param_flag == 1) {
do_something;
}
有关结构选项的详细信息,请参阅 man getopt_long。
- 如何将enable-if与模板参数和参数包一起使用
- 如何使我的 sizeof sum 结构与空参数包一起工作
- 概念可以与模板模板参数一起使用吗?
- 为什么当我尝试将priority_queue与参数一起使用作为指向结构的指针时会弹出错误
- 标准::原子::compare_exchange与两个memory_order参数一起使用的真实示例
- 如何在 C++ 中将 typedef 与类初始值设定项参数一起使用?
- 我可以将"token pasting operator"与"const"模板参数一起使用吗?
- 哪个强制转换应与模板类参数一起使用,dynamic_cast或reinterpet_cast?
- 将 boost::function 与指向派生类的共享指针的参数一起使用
- 如何将 #ifndef 与宏参数一起使用
- 如何将初始值设定项与右值引用参数一起使用 // 为什么不能使用另一个 C 样式数组变量初始化 C 样式数组
- 将模板类与引用非类型模板参数一起使用时出现链接器错误
- 如何将QDebug()与QT中的两个参数一起使用
- 将函数与指针参数一起使用作为另一个函数的参数
- 是否可以在C++中将宏条件与模板参数一起使用
- 提升program_options解析选项和参数一起
- 在C++中,如何仅将长选项与必需参数一起使用
- 当通过引用指针将函数与参数一起使用时会发生什么
- 将typedef与构造函数参数一起使用
- 将函数指针上的参数与默认值参数一起丢弃是否有效