如何使用getopt_long解析多个参数
How do I use getopt_long to parse multiple arguments?
#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!
getopt 在处理完所有选项参数后返回 -1。--stuff
被识别为接受参数的选项,在本例中为 someArg1
.someArg2
arg 不以 -
或 --
开头,因此不是一个选项。默认情况下,这将排列到 argv
的末尾。getopt 返回 -1 后,所有非选项参数将从 optind
argv
到 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;
}
}
在./a.out --stuff someArg1 someArg2
行中,shell 将三个参数解释为 a.out。您希望 shell 将"someArg1 someArg2"解释为一个参数 - 因此请将单词放在引号中:
./a.out --stuff "someArg1 someArg2"
我正在研究Windows,所以我不得不从这个优秀的来源编译getopt和getopt_long
我修改了 getopt_long.c(下图(以适应两个输入参数。我没有为多个参数的更一般的情况而烦恼,因为这需要比我的时间/需要更多(和更干净(的返工。第二个参数放在另一个全局参数 "optarg2" 中。
如果你不需要从源代码编译getopt,弗兰克上面的回答就更优雅了。
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 -- %sn",
__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 -- %sn",
__progname(nargv[0]), current_argv);
return (BADARG);
}
您还需要在getopt.h中添加一个定义,以根据需要为"two_required_args"或"multiple_args"添加定义。
编辑:我不擅长降价
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-long command-line-arguments
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- C++ 我应该如何解释函数参数long(*pPointer)(OtherClass *const, long)?
- 函数参数可以是char*、long或int.可能吗
- libcurl curl_easy_stopt long参数未正确传递-varg(param,long)
- 我有 3 个错误:期望一个")",期望一个表达式,long 类型的参数与 U32 类型的参数不兼容
- C++无法将'long double'转换为'long double*',因为参数'1'为"long
- 警告:格式 '%d' 需要类型"int",但参数 6 的类型为 'long int'
- 为什么系统在没有警告的情况下接受作为int参数传递的long int
- 奇怪的DllImport问题,当传递一个LONG参数内存损坏
- 我如何使用3个重载函数(参数的差异是int, long, float)同时只要求一个输入项