C++:Boost program_options:多个参数列表
我目前正在使用 boost::program_options
.我的程序应该将任意数量的任意长度的列表"作为参数(除其他外……).例如,用户应该能够调用
I'm currently working with boost::program_options
. My program is supposed to take as arguments (amongst other things...) an arbitrary number of 'lists' of arbitrary length. For example, the user should be able to call
./myprogram -list item1 item2 item3 -list item1 item2 -list item1 item2
显然,我不想得到一个包含所有项目的列表/向量作为结果,但是(在这种情况下)三个列表/向量(或者,例如,一个包含元素)每个列表有两个或三个项目(每个项目应该是一个字符串,但我想这并不重要).正如我之前所说,列表的数量(以及每个列表的项目数量!)应该是任意的.我如何使用 boost::program_options
做到这一点?
Obviously, I don't want to get one list/vector with all the items one after the other as a result, but (in this case) three lists/vectors (or, for example, one vector of vectors containing the elements) with two or three items per list (each item is supposed to be a string, but I guess this doesn't matter).
As I said before, the number of lists (as well as the number of items per list!) should be arbitrary.
How can I do that with boost::program_options
?
推荐答案
无需大量额外代码即可完成此操作.秘诀是将解析步骤与存储步骤分开,这在 this answer 中也是如此.
This can be done without a whole lot of extra code. The secret is to separate the parsing step from the storage step, as also done in this answer.
当用户提供选项时,解析器将返回一个包含键/值结构的容器.如果一个选项被多次提交,那么对于每个选项提交,容器将有一个单独的条目.扫描特定选项并根据需要组织其值非常简单.
The parser will return a container of key/value structs as the options are presented from the user. If an option is submitted multiple times then the container will have a separate entry for each option submission. It is quite straightforward to scan for a particular option and organize its values however we want.
这是一个在单独的行上打印出每个输入的多令牌选项的示例:
Here's an example that prints out each input multi-token option on a separate line:
#include <iostream>
#include <string>
#include <vector>
#include <boost/program_options.hpp>
namespace po = boost::program_options;
int main(int argc, char *argv[]) {
// Define a multi-token option.
po::options_description desc("Allowed options");
desc.add_options()
("list", po::value<std::vector<std::string>>()->multitoken(), "multiple values");
// Just parse the options without storing them in a map.
po::parsed_options parsed_options = po::command_line_parser(argc, argv)
.options(desc)
.run();
// Build list of multi-valued option instances. We iterate through
// each command-line option, whether it is repeated or not. We
// accumulate the values for our multi-valued option in a
// container.
std::vector<std::vector<std::string>> lists;
for (const po::option& o : parsed_options.options) {
if (o.string_key == "list")
lists.push_back(o.value);
}
// If we had other normal options, we would store them in a map
// here. In this demo program it isn't really necessary because
// we are only interested in our special multi-valued option.
po::variables_map vm;
po::store(parsed_options, vm);
// Print out the multi-valued option, each separate instance on its
// own line.
for (size_t i = 0; i < lists.size(); ++i) {
for (size_t j = 0; j < lists[i].size(); ++j)
std::cout << lists[i][j] << ' ';
std::cout << '
';
}
return 0;
}
这是一个调用示例(在coliru 直播):
And here's a sample invocation (live at coliru):
$ ./po --list 1 2 3 --list foo bar --list how now brown cow
1 2 3
foo bar
how now brown cow
相关文章