使用' - '作为选项结束标记与boost :: program_options [英] Using '--' as end-of-options marker with 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 option
s (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屋!