我如何使用 getopt_long 处理 c 中的参数
我真的不明白如何使用 getopt_long 函数正确处理 c 中的命令行参数,我创建了以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
int main(int argc, char** argv) {
int next_option;
/* String of short options */
const char *short_options = "hl:k";
/* The array of long options */
const struct option long_options[] = {
{ "help", 0, NULL, 'h' },
{ "launch", 1, NULL, 'l' },
{ "kill", 0, NULL, 'k' },
{ NULL, 0, NULL, 0 }
};
do {
next_option = getopt_long(argc, argv, short_options, long_options, NULL);
switch (next_option) {
case 'h':
/* User requested help */
fprintf(stdout, "HELP\n");
break;
case 'l':
fprintf(stdout, "launching\n");
fprintf(stdout, "Want to launch on port %s\n",\
optarg);
break;
case 'k':
fprintf(stdout, "KILLING\n");
break;
case '?':
/* The user specified an invalid option */
fprintf(stdout, "Requested arg does not exist!\n");
exit(EXIT_FAILURE);
case -1:
/* Done with options */
break;
default:
/* Unexpected things */
fprintf(stdout, "I can't handle this arg!\n");
exit(EXIT_FAILURE);
}
} while(next_option != -1);
return (EXIT_SUCCESS);
}
输出很奇怪,因为我们可以将垃圾数据作为命令行参数传递,而我的程序不检查此错误!我该如何解决这个问题。
执行示例:
$ ./command_line -h garbage
HELP
$ ./command_line --help garbage
HELP
$ ./command_line --launch 1200 garbage
launching
Want to launch on port 1200
$ ./command_line --lBADARG 1200
command_line: unrecognized option `--lBADARG'
Requested arg does not exist!
$ ./command_line -lBADARG 1200
launching
Want to launch on port BADARG
感谢您的帮助。
i don't really understand how can i correctly handle command line arguments in c using getopt_long function, i create this code :
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
int main(int argc, char** argv) {
int next_option;
/* String of short options */
const char *short_options = "hl:k";
/* The array of long options */
const struct option long_options[] = {
{ "help", 0, NULL, 'h' },
{ "launch", 1, NULL, 'l' },
{ "kill", 0, NULL, 'k' },
{ NULL, 0, NULL, 0 }
};
do {
next_option = getopt_long(argc, argv, short_options, long_options, NULL);
switch (next_option) {
case 'h':
/* User requested help */
fprintf(stdout, "HELP\n");
break;
case 'l':
fprintf(stdout, "launching\n");
fprintf(stdout, "Want to launch on port %s\n",\
optarg);
break;
case 'k':
fprintf(stdout, "KILLING\n");
break;
case '?':
/* The user specified an invalid option */
fprintf(stdout, "Requested arg does not exist!\n");
exit(EXIT_FAILURE);
case -1:
/* Done with options */
break;
default:
/* Unexpected things */
fprintf(stdout, "I can't handle this arg!\n");
exit(EXIT_FAILURE);
}
} while(next_option != -1);
return (EXIT_SUCCESS);
}
And the output is strange, cause we can pass garbage data as command line arguments and my program don't check this errors! How can i fix that.
An example of execution :
$ ./command_line -h garbage
HELP
$ ./command_line --help garbage
HELP
$ ./command_line --launch 1200 garbage
launching
Want to launch on port 1200
$ ./command_line --lBADARG 1200
command_line: unrecognized option `--lBADARG'
Requested arg does not exist!
$ ./command_line -lBADARG 1200
launching
Want to launch on port BADARG
Thanks for your help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,发生的事情是这样的:
在这种情况下:
通过给它
--lBADARG
你是说寻找 LONG 参数lBADARG
,但你没有。在这种情况下:
您成功地告诉它使用带有参数的
-l
标志。它的行为符合预期,告诉您参数是BADARG
。如果你尝试
或
或
应该做你所期望的。如果您想获取不是选项的参数,您将在完成 getopt 处理后在 argv 向量中找到它们,因为 getopt_long 可以方便地排列argv 向量将非选项参数保留在那里。
Okay, what's happening is this:
in this case:
by giving it
--lBADARG
you're saying look for the LONG argumentlBADARG
, and you don't have one.in this case:
you're successfully telling it to use the
-l
flag which has an argument. It behaves as expected, telling you that argument isBADARG
.If you try
or
or
that should do what you expect. And if you want to get the arguments that are not options, you'll find them in the argv vector after you've done the getopt processing, because getopt_long conveniently permutes the argv vector to leave non-option arguments there.
garbage
顺利通过的原因是getopt
及其兄弟用于处理选项,而不是所有命令 lne 参数。并非所有参数都是选项。--lBADARG
与-lBADARG
的处理方式不同,原因在于它处理它们的方式不同。--lBADARG
是不带参数的选项lBADARG
,而-lBADARG
是带参数的-l
选项BADARG
。前者未列为有效选项,但后者被列为有效选项。最后一个可能的问题是
BADARG
被视为端口。这是因为getopt
东西既不知道也不关心参数类型,这取决于您的代码。如果你想确保它是数字,你应该检查一下。您很可能希望支持符号端口名称(例如在/etc/ports
中查找)。The reason the
garbage
is getting through okay is becausegetopt
and its brethren are for processing options, not all command lne arguments. Not all arguments are options.The reason that
--lBADARG
is treated differently to-lBADARG
is because of the way it wants to handle them.--lBADARG
is an optionlBADARG
with no parameters while-lBADARG
is the-l
option with a parameter ofBADARG
. The former is not listed as a valid option but the latter is.And the final possible issue is that
BADARG
is being treated as a port. That's because thegetopt
stuff neither knows nor cares about parameter types, that's up to your code. If you want to ensure it's numeric, you should check for that. It may well be that you want to support symbolic port names (looked up in/etc/ports
for example).