2

我想用来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);
    }
}
4

2 回答 2

4

第一个答案是:没有什么能阻止您使用或修改optind. 如果optind < argcthenoptind是 中下一个公共行参数的索引argv,否则没有更多参数。因此,您可以在处理循环中使用该参数,但这是您的责任:

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

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

最后,您的示例代码中缺少许多break语句,这就是为什么-s会被报告为-u.

于 2012-11-12T02:17:15.527 回答
0

如果你这样调用你的程序:

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

在这种情况下,您将获得"127.0.0.1 2012"价值。optarg's'

于 2012-11-12T08:37:09.737 回答