getopt_long()将多个参数解析为单个选项字母

时间:2012-11-12 01:59:41

标签: c getopt

我想使用getopt_long()来解析命令行参数。阅读getopt_long()手册页后,我理解getopt_long()只能在一个选项后解析一个参数。无论如何使用getopt_long()来解析这个命令行:

./a.out -s 127.0.0.1 2012 -u stackoverflow

给出结果:

ip = 127.0.0.1
port = 2012
username = stackoverflow

这是我尝试过的:

while (1) {
    int this_option_optind = optind ? optind : 1;
    int option_index = 0;
    static struct option long_options[] = {
        {"server", required_argument, NULL, 's'},
        {"user", required_argument, NULL, 'u'},
        {0, 0, 0, 0},
    };

    c = getopt_long(argc, argv, "s:u:", long_options, &option_index);
    if (c == -1)
        break;

    switch (c) {

        case 's':
            printf("option %s", long_options[option_index].name);
            if (optarg) {
                printf(" with arg %s", optarg);
            }
            printf("\n");

        case 'u':
            printf("option %s", long_options[option_index].name);
            if (optarg) {
                printf(" with arg %s", optarg);
            }
            printf("\n");

        case '?':
            break;

        default:
            printf("?? getopt returned character code 0%o ??\n", c);
    }
}

2 个答案:

答案 0 :(得分:4)

第一个答案是:没有什么能阻止你使用或修改optind。如果optind < argcoptindargv中下一个公共行参数的索引,否则不再有参数。所以你可以在你的处理循环中使用那个参数,但这是你的责任:

  • 确保optind在范围内(< argc
  • 检查argv[optind]的参数是否是另一个选项(即是否以-开头)
  • 增加optind,以便您使用的参数不会被getopt重新扫描。

第二个答案是:在做一些非标准的事情之前你应该三思。虽然看起来有点打字,但是有充分的理由使用更标准的技术,比如-p PORT选项。对于习惯于标准命令行选项行为的用户来说,文档更容易实现,实现工作更少,而且不那么令人惊讶。

最后,您在示例代码中遗漏了许多break语句,这就是-s报告为-u的原因。

答案 1 :(得分:0)

如果您按照以下方式致电您的计划:

./a.out -s "127.0.0.1 2012" -u stackoverflow

"127.0.0.1 2012"案件optarg的价值为's'