#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!
答案 0 :(得分:7)
getopt 返回-1。 --stuff
被识别为带参数的选项,在本例中为someArg1
。 someArg2
arg不以-
或--
开头,因此不是选项。默认情况下,这将被置换为argv
的末尾。在 getopt 返回-1之后,所有非选项参数将位于从argv
到optind
的{{1}}中:
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
将返回1(不是'1')并将getopt
指向非选项参数:
optarg
答案 1 :(得分:3)
在行./a.out --stuff someArg1 someArg2
中,shell解释了a.out的三个参数。您希望shell将“someArg1 someArg2”解释为一个参数 - 所以将单词放在引号中:
./a.out --stuff "someArg1 someArg2"
答案 2 :(得分:0)
我在Windows上工作,所以我必须从this excellent source编译getopt和getopt_long
我修改了getopt_long.c(下面)以容纳两个输入参数。我没有为多个参数的更一般情况而烦恼,因为这需要比我有时间/需要更多(和更清洁)的返工。第二个参数放在另一个全局的&#34; optarg2&#34;。
中如果您不需要从源代码编译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中为&#34; two_required_args&#34;添加一个定义。或&#34; multiple_args&#34;如你所愿。
编辑:我在降价时表现糟糕
答案 3 :(得分:0)
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;