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

时间:2011-12-22 23:01:10

标签: c command-line-arguments getopt-long

我真的不明白如何使用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

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

好的,发生了什么:

在这种情况下:

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

给它--lBADARG你说要找LONG参数lBADARG,而你没有。{/ p>

在这种情况下:

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

您已成功告诉它使用带有参数的-l标志。它表现得像预期的那样,告诉你参数是BADARG

如果您尝试

$ ./command_line -l 1200

$ ./command_line -l1200

$ ./command_line --launch 1200

应该做你期望的事情。如果你想获得 not 选项的参数,你可以在完成getopt处理后在argv vector 中找到它们,因为getopt_long可以方便地置换argv向量在那里留下非选项参数。

答案 1 :(得分:0)

garbage正常运行的原因是因为getopt及其兄弟用于处理选项,并非所有命令lne参数。并非所有论据都是选项。

--lBADARG-lBADARG的区别对待的原因是它想要处理它们的方式。 --lBADARG是一个没有参数的选项lBADARG,而-lBADARG-l选项,参数为BADARG。前者未被列为有效选项,但后者是。

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