Pat*_*ryk 6 c++ boost boost-program-options c++11
我想创建一个位置,列表程序选项,boost_program_options不允许命名程序选项(如--files).
我有以下代码片段:
#include <boost/program_options.hpp>
#include <iostream>
#include <string>
#include <vector>
namespace po = boost::program_options;
int main(int argc, const char* argv[]) {
po::options_description desc("Allowed options");
desc.add_options()("help", "produce help message")
( "files", po::value<std::vector<std::string>>()->required(), "list of files");
po::positional_options_description pos;
pos.add("files", -1);
po::variables_map vm;
try {
po::store(po::command_line_parser(argc, argv).options(desc).positional(pos).run(), vm);
po::notify(vm);
} catch(const po::error& e) {
std::cerr << "Couldn't parse command line arguments properly:\n";
std::cerr << e.what() << '\n' << '\n';
std::cerr << desc << '\n';
return 1;
}
if(vm.count("help") || !vm.count("files")) {
std::cout << desc << "\n";
return 1;
}
}
Run Code Online (Sandbox Code Playgroud)
问题是我可以读取文件列表作为位置参数列表,如下所示:
./a.out file1 file2 file3
Run Code Online (Sandbox Code Playgroud)
但不幸的是也喜欢这个(我想禁用)
./a.out --files file1 file2 file3
Run Code Online (Sandbox Code Playgroud)
问题还在于产生的帮助:
./a.out
Couldn't parse command line arguments properly:
the option '--files' is required but missing
Allowed options:
--help produce help message
--files arg list of files
Run Code Online (Sandbox Code Playgroud)
所以我想要的场景会更像(os类似):
./a.out
Couldn't parse command line arguments properly:
[FILES ...] is required but missing
Allowed options:
--help produce help message
--optionx some random option used in future
[FILE ...] list of files
Run Code Online (Sandbox Code Playgroud)
我files从中删除选项后desc.add_option()(...)停止工作,所以我相信我需要它.
至于标题中提出的问题,"如何为boost :: program_options的位置选项添加描述?",库中没有为此提供的功能.您需要自己处理该部分.
至于问题的主体......它是可能的,但是以略微圆润的方式.
位置选项将每个位置映射到名称,并且名称需要存在.从我在code(cmdline.cpp)中可以看出,unregistered不会为位置参数设置标志.[ 1 ],[ 2 ]
所以,为了做你想做的事,我们可以做到以下几点:
--files显示在帮助中的选项.您需要自己为位置选项显示适当的帮助,但这与以前没有什么不同.variables_map.--files帮助在这里,我们利用了可以options_description使用add(...)成员函数创建复合的事实:
po::options_description desc_1;
// ...
po::options_description desc_2;
// ...
po::options_description desc_composite;
desc_composite.add(desc_1).add(desc_2);
Run Code Online (Sandbox Code Playgroud)
因此,我们可以将我们的files选项放入隐藏options_description,并创建一个我们将仅用于解析阶段的复合.(见下面的代码)
--files我们需要截取解析和存储它们之间的选项列表variables_map.
所述run()的方法command_line_parser返回的一个实例basic_parsed_options,其成员options持有的向量basic_option号第 每个已解析的参数都有一个元素,并且从0任何非位置选项的位置开始枚举任何位置选项-1.我们可以使用它来执行我们自己的验证,并在我们将其--files视为显式(非位置)参数时引发错误.
#include <boost/program_options.hpp>
#include <iostream>
#include <string>
#include <vector>
namespace po = boost::program_options;
int main(int argc, const char* argv[])
{
std::vector<std::string> file_names;
po::options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("test", "test option");
std::string const FILES_KEY("files");
// Hide the `files` options in a separate description
po::options_description desc_hidden("Hidden options");
desc_hidden.add_options()
(FILES_KEY.c_str(), po::value(&file_names)->required(), "list of files");
// This description is used for parsing and validation
po::options_description cmdline_options;
cmdline_options.add(desc).add(desc_hidden);
// And this one to display help
po::options_description visible_options;
visible_options.add(desc);
po::positional_options_description pos;
pos.add(FILES_KEY.c_str(), -1);
po::variables_map vm;
try {
// Only parse the options, so we can catch the explicit `--files`
auto parsed = po::command_line_parser(argc, argv)
.options(cmdline_options)
.positional(pos)
.run();
// Make sure there were no non-positional `files` options
for (auto const& opt : parsed.options) {
if ((opt.position_key == -1) && (opt.string_key == FILES_KEY)) {
throw po::unknown_option(FILES_KEY);
}
}
po::store(parsed, vm);
po::notify(vm);
} catch(const po::error& e) {
std::cerr << "Couldn't parse command line arguments properly:\n";
std::cerr << e.what() << '\n' << '\n';
std::cerr << visible_options << '\n';
return 1;
}
if (vm.count("help") || !vm.count("files")) {
std::cout << desc << "\n";
return 1;
}
if (!file_names.empty()) {
std::cout << "Files: \n";
for (auto const& file_name : file_names) {
std::cout << " * " << file_name << "\n";
}
}
}
Run Code Online (Sandbox Code Playgroud)
有效选项:
>example a b c --test d e
Files:
* a
* b
* c
* d
* e
Run Code Online (Sandbox Code Playgroud)
选项无效:
>example a b c --files d e
Couldn't parse command line arguments properly:
unrecognised option 'files'
Allowed options:
--help produce help message
--test test option
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2968 次 |
| 最近记录: |