我如何使用 getopt_long 处理 c 中的参数

发布于 2024-12-22 19:32:17 字数 1993 浏览 1 评论 0原文

我真的不明白如何使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

双马尾 2024-12-29 19:32:17

好吧,发生的事情是这样的:

在这种情况下:

$ ./command_line --lBADARG 1200
command_line: unrecognized option `--lBADARG'
Requested arg does not exist!

通过给它 --lBADARG 你是说寻找 LONG 参数 lBADARG,但你没有。

在这种情况下:

$ ./command_line -lBADARG 1200
launching
Want to launch on port BADARG

您成功地告诉它使用带有参数的 -l 标志。它的行为符合预期,告诉您参数是 BADARG

如果你尝试

$ ./command_line -l 1200

$ ./command_line -l1200

$ ./command_line --launch 1200

应该做你所期望的。如果您想获取不是选项的参数,您将在完成 getopt 处理后在 argv 向量中找到它们,因为 getopt_long 可以方便地排列argv 向量将非选项参数保留在那里。

Okay, what's happening is this:

in this case:

$ ./command_line --lBADARG 1200
command_line: unrecognized option `--lBADARG'
Requested arg does not exist!

by giving it --lBADARG you're saying look for the LONG argument lBADARG, and you don't have one.

in this case:

$ ./command_line -lBADARG 1200
launching
Want to launch on port BADARG

you're successfully telling it to use the -l flag which has an argument. It behaves as expected, telling you that argument is BADARG.

If you try

$ ./command_line -l 1200

or

$ ./command_line -l1200

or

$ ./command_line --launch 1200

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.

蓝咒 2024-12-29 19:32:17

garbage 顺利通过的原因是 getopt 及其兄弟用于处理选项,而不是所有命令 lne 参数。并非所有参数都是选项。

--lBADARG-lBADARG 的处理方式不同,原因在于它处理它们的方式不同。 --lBADARG 是不带参数的选项 lBADARG,而 -lBADARG 是带参数的 -l 选项BADARG。前者未列为有效选项,但后者被列为有效选项。

最后一个可能的问题是 BADARG 被视为端口。这是因为 getopt 东西既不知道也不关心参数类型,这取决于您的代码。如果你想确保它是数字,你应该检查一下。您很可能希望支持符号端口名称(例如在 /etc/ports 中查找)。

The reason the garbage is getting through okay is because getopt 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 option lBADARG with no parameters while -lBADARG is the -l option with a parameter of BADARG. 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 the getopt 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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文