getopt_long() 带有可选参数的选项
getopt_long() option with optional argument
我正在尝试使用 getopt_long() 创建一个带有可选参数的选项。
这是我的代码:
static struct option long_options[] = {
{"help", no_argument, NULL, 'h'},
{"debug", no_argument, NULL, 'd'},
{"config", optional_argument, NULL, 'c'},
{NULL, 0, NULL, 0}
};
while ((ch = getopt_long(argc, argv, "hdc::", long_options, NULL)) != -1) {
// check to see if a single character or long option came through
switch (ch) {
case 'h':
opt.help = true;
break;
case 'd':
opt.debug = true;
break;
case 'c':
printf("C-Option: %s\n", optarg);
if (optarg != NULL) {
opt.configFile = optarg;
}
break;
}
}
我正在尝试使 -c
的参数可选,这样您就可以 运行 使用这些选项的程序:
-c test.cfg
--> optarg = "test.cfg"
-c
--> optarg = null
如果我设置 c::
,那么 optarg
总是 null
。
如果我设置 c:
比我得到一个错误:option requires an argument -- 'c'
我做错了什么?我可以设置其他选项吗?
来自man pages:
If the option has an optional argument, it must be written directly after the option character if present.
您的代码按预期工作:
./a.out -c some_argument --> "C-Option: (null)"
./a.out -csome_argument --> "C-Option: some_argument"
./a.out -c=some_argument --> "C-Option: =some_argument"
您可以考虑在可选参数名称前加上 '='
,如上例所示。 another question 讨论了这个问题。
更新
我在上面提到的 link 到 other question 中看到了这个问题的一个很好的解决方案。这个想法是在带有参数的选项之后检查 argv[]
中的下一个字符串是否是一个选项。如果不是,则假定它是一个参数。然后处理该参数,并相应地推进 optind
。以下是如何将此想法应用于您的问题:
case 'c':
if (optarg == NULL && argv[optind] != NULL
&& argv[optind][0] != '-') { // not an option
printf("C-Option: %s\n", argv[optind]);
opt.configFile = argv[optind];
++optind;
} else { // handle case of argument immediately after option
printf("C-Option: %s\n", optarg);
if (optarg != NULL) {
opt.configFile = optind;
}
break;
此代码将产生以下输出:
./a.out -csome_argument --> "C-Option: some_argument"
./a.out -c some_argument --> "C-Option: some_argument"
我正在尝试使用 getopt_long() 创建一个带有可选参数的选项。
这是我的代码:
static struct option long_options[] = {
{"help", no_argument, NULL, 'h'},
{"debug", no_argument, NULL, 'd'},
{"config", optional_argument, NULL, 'c'},
{NULL, 0, NULL, 0}
};
while ((ch = getopt_long(argc, argv, "hdc::", long_options, NULL)) != -1) {
// check to see if a single character or long option came through
switch (ch) {
case 'h':
opt.help = true;
break;
case 'd':
opt.debug = true;
break;
case 'c':
printf("C-Option: %s\n", optarg);
if (optarg != NULL) {
opt.configFile = optarg;
}
break;
}
}
我正在尝试使 -c
的参数可选,这样您就可以 运行 使用这些选项的程序:
-c test.cfg
--> optarg = "test.cfg"
-c
--> optarg = null
如果我设置 c::
,那么 optarg
总是 null
。
如果我设置 c:
比我得到一个错误:option requires an argument -- 'c'
我做错了什么?我可以设置其他选项吗?
来自man pages:
If the option has an optional argument, it must be written directly after the option character if present.
您的代码按预期工作:
./a.out -c some_argument --> "C-Option: (null)"
./a.out -csome_argument --> "C-Option: some_argument"
./a.out -c=some_argument --> "C-Option: =some_argument"
您可以考虑在可选参数名称前加上 '='
,如上例所示。 another question 讨论了这个问题。
更新
我在上面提到的 link 到 other question 中看到了这个问题的一个很好的解决方案。这个想法是在带有参数的选项之后检查 argv[]
中的下一个字符串是否是一个选项。如果不是,则假定它是一个参数。然后处理该参数,并相应地推进 optind
。以下是如何将此想法应用于您的问题:
case 'c':
if (optarg == NULL && argv[optind] != NULL
&& argv[optind][0] != '-') { // not an option
printf("C-Option: %s\n", argv[optind]);
opt.configFile = argv[optind];
++optind;
} else { // handle case of argument immediately after option
printf("C-Option: %s\n", optarg);
if (optarg != NULL) {
opt.configFile = optind;
}
break;
此代码将产生以下输出:
./a.out -csome_argument --> "C-Option: some_argument"
./a.out -c some_argument --> "C-Option: some_argument"