【问题标题】:getopt_long() option with optional argument带有可选参数的 getopt_long() 选项
【发布时间】:2017-03-28 09:54:29
【问题描述】:

我正在尝试使用 getopt_long() 创建一个带有可选参数的选项。

这是我的代码:

static struct option long_options[] = {
   {"help",   no_argument,      NULL, 'h'},
   {"debug",  no_argument,      NULL, 'd'},
   {"config", optional_argument, NULL, 'c'},
   {NULL, 0, NULL, 0}
};

while ((ch = getopt_long(argc, argv, "hdc::", long_options, NULL)) != -1) {
        // check to see if a single character or long option came through
        switch (ch) {
            case 'h':
                opt.help = true;
                break;
            case 'd':
                opt.debug = true;
                break;
            case 'c':
                printf("C-Option: %s\n", optarg);
                if (optarg != NULL) {
                    opt.configFile = optarg;
                }
                break;
        }
    }

我正在尝试将 -c 的参数设为可选,以便您可以使用以下选项运行程序:

-c test.cfg --> optarg = "test.cfg"

-c --> optarg = null

如果我设置c:: 而不是optarg 总是null

如果我设置了c:,我会得到一个错误:option requires an argument -- 'c'

我做错了什么?我可以设置其他选项吗?

【问题讨论】:

  • @DavidBowling 不适合我
  • @DavidBowling 那太好了
  • 为什么不定义两个选项:--opt-1_with-arg-opt-1_use-default?或更短:--o1a--o1d 或更短:--o--od ;-)

标签: c getopt


【解决方案1】:

来自man pages

如果选项有可选参数,则必须直接写在选项字符之后。

您的代码按预期工作:

./a.out -c some_argument --> "C-Option: (null)"
./a.out -csome_argument  --> "C-Option: some_argument"
./a.out -c=some_argument --> "C-Option: =some_argument"

您可以考虑在可选参数名称前加上'=',如上例所示。这是讨论该问题的another question

更新

我在上面提到的other question 的链接中看到了一个很好的解决方案。这个想法是在一个带有参数的选项之后检查argv[] 中的下一个字符串是否是一个选项。如果不是,则假定它是一个参数。然后处理参数,并相应地推进optind。以下是如何将此想法应用于您的问题:

case 'c':
            if (optarg == NULL && argv[optind] != NULL
                && argv[optind][0] != '-') {            // not an option
                printf("C-Option: %s\n", argv[optind]);
                opt.configFile = argv[optind];
                ++optind;
            } else {  // handle case of argument immediately after option
                printf("C-Option: %s\n", optarg);
                if (optarg != NULL) {
                    opt.configFile = optind;
            }
            break;

此代码将产生以下输出:

./a.out -csome_argument  --> "C-Option: some_argument"
./a.out -c some_argument --> "C-Option: some_argument"

【讨论】:

    猜你喜欢
    • 2021-02-28
    • 2012-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    相关资源
    最近更新 更多