【问题标题】:Using long_options to parse options with an arbitrary number of required_arguments使用 long_options 解析具有任意数量 required_arguments 的选项
【发布时间】:2019-04-28 09:11:47
【问题描述】:

我正在尝试使用 long_options[] 将从终端输入的不同选项解析为 C++ 程序。我的选项结构看起来像:

static struct option long_options[] = {
  // *name, has_arg, *flag, val
  {"help",      no_argument,        0,  'h'},
  {"debug",     no_argument,        0,  0},
  {"seed",      required_argument,  0,  's'},
  ...
}

然后我会使用 getopt_long 来读取参数如下:

while (true) {

    int option_index (0);
    int c = getopt_long (argc, argv, "hs:t:iT:N:M:m:V:l:w:P:rR:b:d:a:", long_options, &option_index);
    if (c == -1) break;

    switch (c) {

        case 'h':
        print_help ();

        case 's':
        parameters.seed = atoi(optarg);
        break;

        case 0:
        if (long_options[option_index].flag != 0) break;
        else if (strcmp(long_options[option_index].name, "debug") == 0) parameters.debug = true;
        ...
        break;
    }
}

参数传递给optarg,据我了解是char*或std::string类型,如上图。

当我想到一种方法来设置具有所需数量的两个或更多参数的选项参数时,问题就来了。例如,我想设置一个选项,允许用户方便地定义分布参数。我希望从终端调用如下:

./program --distribution mean sd
./program --distribution mean sd n

但似乎 long_options 默认只需要一个选项参数,因此上例中的 sd 预计会被解析为单独的选项参数。

如何更改此默认行为?谢谢!

【问题讨论】:

    标签: c++ getopt


    【解决方案1】:

    You can't,这不是惯例。

    要为您的应用程序提供非正统的命令行参数结构,您必须编写自己的解析器。

    一种解决方法是要求您的用户在 one 参数中发送多个单词:

    ./program --distribution 'mean sd n'
    

    尽管您仍然需要自己解析生成的多字字符串。

    Boost.ProgramOptions 比旧的getopt 更灵活一点,不会过多偏离命令行参数的公认“标准”实践,但确定它是否符合您的要求需要研究。

    【讨论】:

    • 文档中似乎很清楚。我正在尝试使用该 optind 索引和getopt() 调用以更好地了解其行为方式。据我现在了解它们,我相信可以相应地更改索引以调用每个“附加”选项值
    • Optind 已返回给您。它不会驱动内部行为。
    【解决方案2】:

    Optarg 应仅被视为输入。

    也就是说,它是指向原始 argv 成员之一的原始指针。

    最后,所有剩余未使用的参数在 argv 中重新组合,以供您用作输入文件名等,但当然,您将丢失它们在参数中的顺序。

    如果您在开始时制作自己的 argv 副本,那么您可以轻松找到 getopt 指示的 optarg,并自己解析接受每个参数,直到下一个“-”。 Getopt 会将这些附加参数设为“未使用”。

    如果您还想接受任何未使用的参数,则需要对 argv 执行更多过滤以丢弃已用完的其他选项。

    虽然比较麻烦,但相对安全。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-27
      • 1970-01-01
      • 2017-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-04
      • 1970-01-01
      相关资源
      最近更新 更多