如何使用 getopt_long 解析多个参数?
Posted
技术标签:
【中文标题】如何使用 getopt_long 解析多个参数?【英文标题】:How do I use getopt_long to parse multiple arguments? 【发布时间】:2012-02-07 05:08:27 【问题描述】:#include <iostream>
#include <getopt.h>
#define no_argument 0
#define required_argument 1
#define optional_argument 2
int main(int argc, char * argv[])
std::cout << "Hello" << std::endl;
const struct option longopts[] =
"version", no_argument, 0, 'v',
"help", no_argument, 0, 'h',
"stuff", required_argument, 0, 's',
0,0,0,0,
;
int index;
int iarg=0;
//turn off getopt error message
opterr=1;
while(iarg != -1)
iarg = getopt_long(argc, argv, "s:vh", longopts, &index);
switch (iarg)
case 'h':
std::cout << "You hit help" << std::endl;
break;
case 'v':
std::cout << "You hit version" << std::endl;
break;
case 's':
std::cout << "You hit stuff" << std::endl;
if(optarg)
std::cout << "Your argument(s): " << optarg << std::endl;
break;
std::cout << "GoodBye!" << std::endl;
return 0;
期望的输出:
./a.out --stuff someArg1 someArg2
Hello
You hit stuff
Your agument(s): someArg1 someArg2
GoodBye!
【问题讨论】:
它只捕获 1 个参数:实际输出 Hello You hit stuff Your argument(s): someArg1 GoodBye! 【参考方案1】:getopt 在处理完所有 option 参数后返回 -1。 --stuff
被识别为带有参数的选项,在本例中为 someArg1
。 someArg2
arg 不以 -
或 --
开头,因此它不是选项。默认情况下,这将被置换到argv
的末尾。 getopt 返回 -1 后,所有非选项 args 将在 argv
从 optind
到 argc-1
:
while (iarg != -1)
iarg = getopt_long(argc, argv, "s:vh", longopts, &index);
// ...
for (int i = optind; i < argc; i++)
cout << "non-option arg: " << argv[i] << std::endl;
如果您在optstring
的开头添加一个-
,getopt
将返回1(不是'1')并将optarg
指向非选项参数:
while (iarg != -1)
iarg = getopt_long(argc, argv, "-s:vh", longopts, &index);
switch (iarg)
// ...
case 1:
std::cout << "You hit a non-option arg:" << optarg << std::endl;
break;
【讨论】:
【参考方案2】:在./a.out --stuff someArg1 someArg2
行中,shell 将三个参数解释为a.out。您希望 shell 将“someArg1 someArg2”解释为一个参数 - 所以将这些词放在引号中:
./a.out --stuff "someArg1 someArg2"
【讨论】:
【参考方案3】:我在 windows 上工作,所以我必须从 this excellent source 编译 getopt 和 getopt_long
我修改了 getopt_long.c(如下)以容纳两个输入参数。我没有为多个参数的更一般情况而烦恼,因为这需要比我有时间/需要的更多(和更清洁)的返工。第二个参数放置在另一个全局变量“optarg2”中。
如果您不需要从源代码编译 getopt,上面 Frank 的回答更优雅。
extern char * optarg2
.
.
.
int getopt_long(nargc, nargv, options, long_options, index)
.
.
.
if (long_options[match].has_arg == required_argument ||
long_options[match].has_arg == optional_argument ||
long_options[match].has_arg == two_req_arguments)
if (has_equal)
optarg = has_equal;
else
optarg = nargv[optind++];
if (long_options[match].has_arg == two_req_arguments)
optarg2 = nargv[optind++];
if ((long_options[match].has_arg == required_argument ||
long_options[match].has_arg == two_req_arguments)
&& (optarg == NULL))
/*
* Missing argument, leading :
* indicates no error should be generated
*/
if ((opterr) && (*options != ':'))
(void)fprintf(stderr,
"%s: option requires an argument -- %s\n",
__progname(nargv[0]), current_argv);
return (BADARG);
if ((long_options[match].has_arg == two_req_arguments)
&& (optarg2 == NULL))
/*
* Missing 2nd argument, leading :
* indicates no error should be generated
*/
if ((opterr) && (*options != ':'))
(void)fprintf(stderr,
"%s: option requires 2nd argument -- %s\n",
__progname(nargv[0]), current_argv);
return (BADARG);
您还需要在 getopt.h 中为“two_required_args”或“multiple_args”添加一个您认为合适的定义。
编辑:我不擅长降价
【讨论】:
【参考方案4】:optarg 指向 "someArg1" 并且 argv[optind] 是 "someArg2" 如果它存在并且不是一个选项。您可以简单地使用它,然后通过增加 optind 来使用它。
case 's':
std::cout << "You hit stuff" << std::endl;
if (optind < argc && argv[optind][0] != '-')
std::cout << "Your argument(s): " << optarg << argv[optind] << std::endl;
optind++;
else
printusage();
break;
请注意,这可以用于任意数量的参数:
case 's':
std::cout << "You hit stuff." << std::endl;
std::cout << "Your arguments:" std::endl << optarg << std::endl;
while (optind < argc && argv[optind][0] != '-')
std::cout << argv[optind] << std::endl;
optind++;
break;
c++getopt-longcommand-line-arguments
【讨论】:
你应该指定标签以上是关于如何使用 getopt_long 解析多个参数?的主要内容,如果未能解决你的问题,请参考以下文章
[总结]函数getopt(),getopt_long及其参数optind
C语言linux getopt_long()函数(命令行解析)(getoptgetopt_long_only)(短选项 -,长选项 --)(option结构体)