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

C getopt_long()将多个参数解析为单个选项字母,c,getopt,C,Getopt,我想使用getopt_long()来解析命令行参数。阅读了getopt_long()手册页后,我了解到getopt_long()只能在一个选项后解析一个参数。是否仍然可以使用getopt_long()像这样解析此命令行: ./a.out -s 127.0.0.1 2012 -u stackoverflow ./a.out -s "127.0.0.1 2012" -u stackoverflow 要给出结果: ip = 127.0.0.1 port = 2012 username = stac

我想使用
getopt_long()
来解析命令行参数。阅读了
getopt_long()
手册页后,我了解到
getopt_long()
只能在一个选项后解析一个参数。是否仍然可以使用
getopt_long()
像这样解析此命令行:

./a.out -s 127.0.0.1 2012 -u stackoverflow
./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);
    }
}

第一个答案是:没有任何东西可以阻止您使用或修改
optind
。如果
optind
,则
optind
argv
中下一个公共行参数的索引,否则就没有其他参数了。因此,您可以在处理循环中使用该参数,但这是您的责任:

  • 确保
    optind
    在范围内(
  • 检查
    argv[optind]
    处的参数是否是另一个选项(即它是否以
    -
    开头)
  • 递增
    optind
    ,使您使用的参数不会被
    getopt
    重新扫描
第二个答案是:在做这种非标准的事情之前,你应该三思而后行。虽然它看起来更像是一种输入,但是有很好的理由使用更标准的技术,比如
-p端口
选项。对于习惯于标准命令行选项行为的用户来说,它更易于记录,实现工作量更少,也不那么令人惊讶


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

第一个答案是:没有任何东西可以阻止您使用或修改
选项。如果
optind
,则
optind
argv
中下一个公共行参数的索引,否则就没有其他参数了。因此,您可以在处理循环中使用该参数,但这是您的责任:

  • 确保
    optind
    在范围内(
  • 检查
    argv[optind]
    处的参数是否是另一个选项(即它是否以
    -
    开头)
  • 递增
    optind
    ,使您使用的参数不会被
    getopt
    重新扫描
第二个答案是:在做这种非标准的事情之前,你应该三思而后行。虽然它看起来更像是一种输入,但是有很好的理由使用更标准的技术,比如
-p端口
选项。对于习惯于标准命令行选项行为的用户来说,它更易于记录,实现工作量更少,也不那么令人惊讶


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

,如果您这样调用程序:

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

's'
案例中,您将获得
“127.0.0.1 2012”
作为
optarg
的值。

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

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

您将获得
“127.0.0.1 2012”
作为
optarg
的案例中的值。

您是否考虑添加
-p
/
--port
标志?或者只是传递
主机:端口
,这是相当标准的吗?你能展示一些代码吗?。。。这与你的
-u
-s
标志完全相同。但是我如何根据-p生成-s,所以当我给出参数-s时,我也必须给出参数-p?@Kevin这并没有真正回答他的问题。如果它是像
--server=--clients=…
这样的东西,您考虑过添加
-p
/
--port
标志吗?或者只是传递
主机:端口
,这是相当标准的吗?你能展示一些代码吗?。。。这与你的
-u
-s
标志完全相同。但是我如何根据-p生成-s,所以当我给出参数-s时,我也必须给出参数-p?@Kevin这并没有真正回答他的问题。如果它是像
--server=--clients=…
这样的东西呢。替代使用
-p port
的选项是
-s server:port
。对于服务器/客户端问题,您建议如何重新组织命令行选项?也就是说,同步一个视频播放器的多个实例,其中一个被指定为服务器角色,而另一个则被指定为客户端?很好地说。替代使用
-p port
的选项是
-s server:port
。对于服务器/客户端问题,您建议如何重新组织命令行选项?例如,同步一个视频播放器的多个实例,其中一个被指定为服务器角色,而另一个被指定为客户端?