使用' - '作为选项结束标记与boost :: program_options [英] Using '--' as end-of-options marker with boost::program_options

查看:592
本文介绍了使用' - '作为选项结束标记与boost :: program_options的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

指示命令行程序选项结束的传统方法是使用选项 - 。如何获取boost :: program_options来识别这个选项并接受命令行的其余部分作为位置参数?以下不工作:

The traditional way of indicating the end of options for command line programs is with the option --. How can I get boost::program_options to recognize this as an option and accept the rest of the command line as positional arguments? The following doesn't work:

namespace po = boost::program_options;

po::positional_options_description posOpts;
posOpts.add("keywords", 1);
posOpts.add("input", 1);

std::vector<std::string> final_args;

po::options_description desc("Allowed Options");
desc.add_options()
  ...
  ("", po::value< std::vector<std::string> >(&final_args)->multitoken(), "end of options")
  ...
  ;

po::command_line_parser(argc, argv).options(desc).positional(posOpts).run();

如果我给 foo bar 我在 final_args (如预期),但是当我给 - foo bar 作为参数会期望找到 final_args [0] ==foo final_args [1] ==bar) 。我假设这里 - 是一个长参数,以空字符串作为其参数名称。如果相反,它应该被解释为一个短的参数,以 - 作为参数名称,如何指定?将参数规范从更改为, - 不会影响结果,请参阅

If I give foo bar as arguments, I get nothing in final_args (as expected), but also when I give -- foo bar as arguments (when I would expect to find final_args[0] == "foo" and final_args[1] == "bar"). I'm assuming here that -- is a long argument with the empty string as its argument name. If, instead, it's supposed to be interpreted as a short argument, with - as the argument name, how do I specify that? Changing the argument specification from "" to ",-" doesn't affect the result, so far as I can see.

如何获得boost :: program_options来正确处理 -

How does one get boost::program_options to handle -- correctly?

编辑:创建 extra_style_parser ,尝试执行Tim Sylvester的建议:

Here's an attempt to do what Tim Sylvester suggested by creating an extra_style_parser:

std::vector<po::option> end_of_opts_parser(std::vector<std::string>& args) {
  std::vector<po::option> result;

  std::vector<std::string>::const_iterator i(args.begin());
  if (i != args.end() && *i == "--") {
    for (++i; i != args.end(); ++i) {
      po::option opt;
      opt.string_key = "pargs";
      opt.original_tokens.push_back(*i);
      result.push_back(opt);
    }

    args.clear();
  }

  return result;
}

pargs已添加到如下选项中:

"pargs" was added to the options like this:

("pargs", po::value< std::vector<std::string> >(&pargs), "positional arguments")

c $ c> - 在参数列表中导致 required_option 异常。 (我得到类似的结果,如果不是为每个尾arg, po :: option ,我把它们包装到 po :: option :: original_tokens c。

Running this with a -- in the argument list causes a required_option exception. (I get similar results if instead of making a po::option for each trailing arg, I pack them all into po::option::original_tokens in one po::option.)

推荐答案

我有同样的问题,但放弃了。

I had this same question, but gave up on it.

我相信这样做的方法是调用 program_options :: command_line_parser :: extra_style_parser(),传递一个函数,它通过引用获取一个字符串的向量并返回一个 option c $ c> style_parser typedef in cmdline.hpp )。

I believe the way to do this is to call program_options::command_line_parser::extra_style_parser(), passing it a function that takes a vector of string by reference and returns a vector of options (see the style_parser typedef in cmdline.hpp).

您的函数将需要检测到第一个令牌是 - ,创建一个新的选项对象,将输入中的所有其余标记放入选项的值向量中,并清空输入向量。在 libs / program_options / src / cmdline.cpp program_options :: detail :: cmdline :: parse_long_option >

Your function will need to detect that the first token is "--", create a new option object, place all the rest of the tokens in the input into the option's value vector and empty the input vector. See program_options::detail::cmdline::parse_long_option, etc., in libs/program_options/src/cmdline.cpp for something to start with.

您可能需要注册一个特定的选项值,以便您可以轻松找到这个特殊的选项

You'll probably need to register a specific option value to use so that you can easily find this special option object at the end of the parsing and extract the set of additional non-option parameters from it.

我希望我能给你一些代码但我从来没有真正做到这一点,我最终只是采取附加参数一行一个stdin。

I wish I could give you some code but I never got around to actually doing this, I ended up just taking the additional parameters one-per-line on stdin.

编辑:

我觉得很难指出你没有解决问题的方向,所以我回去了,让它工作。问题是,您的位置参数条目未设置为接受多个令牌,并且您未填充 program_options 代码期望两者或它不工作。

I felt bad about pointing you in a direction that didn't solve the problem, so I went back and got it working. The problem is that your positional argument entry wasn't set up to accept multiple tokens and you weren't filling in the value. The program_options code expects both or it doesn't work.

以下是适用于我的完整代码: / p>

Here's the complete code that works for me:

#include <boost/program_options.hpp>
#include <iostream>

namespace po = boost::program_options;
typedef std::vector<std::string> stringvec;

std::vector<po::option> end_of_opts_parser(stringvec& args) {
  std::vector<po::option> result;
  stringvec::const_iterator i(args.begin());
  if (i != args.end() && *i == "--") {
    for (++i; i != args.end(); ++i) {
      po::option opt;
      opt.string_key = "pargs";
      opt.value.push_back(*i);      //  <== here
      opt.original_tokens.push_back(*i);
      result.push_back(opt);
    }
    args.clear();
  }
  return result;
}

int main(int argc, char* argv[])
{
    po::options_description desc("Allowed Options");
    desc.add_options()
        ("help,h", "produce help message")
        ("pargs", po::value<stringvec>()->multitoken(), "positional arguments");
    //                          and here     ^^^^^^^^^^^^^

    po::command_line_parser clparser(argc, argv);
    clparser.extra_style_parser(end_of_opts_parser);

    po::variables_map vm;
    po::store(clparser.options(desc).run(), vm);
    po::notify(vm);

    bool const help = !vm["help"].empty();
    std::cout << "help = " << help << " - ";

    // in addition, you don't need to use a separate vector of strings:    
    stringvec const& pargs = vm["pargs"].as<stringvec>();
    std::copy(pargs.begin(), pargs.end(),
        std::ostream_iterator<std::string>(std::cout, ","));

    return 0;
}

运行时使用 -h - foo bar baz 它输出 help = 1 - foo,bar,baz,

这篇关于使用' - '作为选项结束标记与boost :: program_options的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆