【发布时间】:2015-08-27 16:33:33
【问题描述】:
我已经实现了一个路由,通过遍历po::variable_map 来打印出我的boost::program_options 对象中可用的所有选项及其当前值。
有了这个,我可以直接打印选项的长名称及其值。但是,我不知道如何从长选项名称中检索短选项名称(即来自 --help 的 -h)。有什么建议吗?
【问题讨论】:
我已经实现了一个路由,通过遍历po::variable_map 来打印出我的boost::program_options 对象中可用的所有选项及其当前值。
有了这个,我可以直接打印选项的长名称及其值。但是,我不知道如何从长选项名称中检索短选项名称(即来自 --help 的 -h)。有什么建议吗?
【问题讨论】:
我记得在最近的一个回答中描述了为什么variable_map“为时已晚”无法了解选项描述:
简而言之,variable_map 位于库的 Storage Component 中,因此与选项描述(位于 Options Description Component 中)隔离。
您可以使用中间结果,即Parsers Component 的原始输出:
解析结果作为
parsed_options类的实例返回。通常,该对象直接传递给存储组件。不过也可以直接使用,也可以做一些额外的处理
所以,让我们在这里尝试制作一个示例:
po::parsed_options const intermediate = po::parse_command_line(ac, av, desc);
//////////////////////////////////
// print the extended usage info as per the question
//
for (auto& entry : intermediate.options)
{
po::option_description const& opt = desc.find(entry.string_key, false, false, false);
std::cout << "\nActual tokens involved: ";
for (auto& tok : entry.original_tokens)
std::cout << "'" << tok << "' ";
for (std::string const& v : entry.value)
std::cout << "\nAssociated value: " << v;
std::cout << "\n-----------------------------------------------------------\n";
std::cout << "opt.format_name() : " << opt.format_name() << "\n";
std::cout << "opt.long_name() : " << opt.long_name() << "\n";
std::cout << "opt.canonical_display_name('-'): " << opt.canonical_display_name(cls::allow_dash_for_short) << "\n";
std::cout << "opt.canonical_display_name('/'): " << opt.canonical_display_name(cls::allow_slash_for_short) << "\n";
std::cout << "opt.canonical_display_name('--'): " << opt.canonical_display_name(cls::allow_long) << "\n";
}
注意:通过按键查找,您实际上也可以使用
variable_map。
打印例如
Actual tokens involved: '-C' '42'
Associated value: 42
-----------------------------------------------------------
opt.format_name() : -C [ --compression ]
opt.long_name() : compression
opt.canonical_display_name('-'): -C
opt.canonical_display_name('/'): /C
opt.canonical_display_name('--'): --compression
Actual tokens involved: '--name' 'santa'
Associated value: santa
-----------------------------------------------------------
opt.format_name() : -n [ --name ]
opt.long_name() : name
opt.canonical_display_name('-'): -n
opt.canonical_display_name('/'): /n
opt.canonical_display_name('--'): --name
Compression level was set to 42.
#include <boost/program_options.hpp>
#include <boost/program_options/detail/parsers.hpp>
#include <iostream>
namespace po = boost::program_options;
namespace cls = po::command_line_style;
int main(int ac, char** av) {
// Declare the supported options.
po::options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("name,n", po::value<std::string>(), "specify the name")
("compression,C", po::value<int>(), "set compression level")
;
po::variables_map vm;
po::parsed_options const intermediate = po::parse_command_line(ac, av, desc);
//////////////////////////////////
// print the extended usage info as per the question
//
for (auto& entry : intermediate.options)
{
po::option_description const& opt = desc.find(entry.string_key, false, false, false);
std::cout << "\nActual tokens involved: ";
for (auto& tok : entry.original_tokens)
std::cout << "'" << tok << "' ";
for (std::string const& v : entry.value)
std::cout << "\nAssociated value: " << v;
std::cout << "\n-----------------------------------------------------------\n";
std::cout << "opt.format_name() : " << opt.format_name() << "\n";
std::cout << "opt.long_name() : " << opt.long_name() << "\n";
std::cout << "opt.canonical_display_name('-'): " << opt.canonical_display_name(cls::allow_dash_for_short) << "\n";
std::cout << "opt.canonical_display_name('/'): " << opt.canonical_display_name(cls::allow_slash_for_short) << "\n";
std::cout << "opt.canonical_display_name('--'): " << opt.canonical_display_name(cls::allow_long) << "\n";
}
//////////////////////////////////
po::store(intermediate, vm);
po::notify(vm);
if (vm.count("help")) {
std::cout << desc << "\n";
return 1;
}
if (vm.count("compression")) {
std::cout << "Compression level was set to "
<< vm["compression"].as<int>() << ".\n";
} else {
std::cout << "Compression level was not set.\n";
}
}
【讨论】: