在 python 中,我可以构建我的optparse实例,这样它会自动将选项和非选项/标志过滤到两个不同的桶中:
(options, args) = parser.parse_args()
Run Code Online (Sandbox Code Playgroud)
使用 boost::program_options,如何检索剩余的非选项和非标志令牌的令牌列表?
例如,如果我的程序有标志
--foo
--bar BAR
Run Code Online (Sandbox Code Playgroud)
然后我传入命令行:
--foo hey --bar BAR you
Run Code Online (Sandbox Code Playgroud)
我怎样才能得到一个仅由“嘿”和“你”组成的列表
我刚刚开始boost::program_options第一次深入研究。我非常喜欢它。然而,我试图用它来完成的事情似乎并不是它的设计者所考虑的。
我想用来boost::program_options解析命令行选项和配置文件。到现在为止还挺好。此外,我希望能够检查更新的设置(例如来自新的配置文件),这些设置可以覆盖我的 variables_map 中先前解析的设置。
当然,我可以做一个单独的解析并尝试合并两个地图。也许这就是我最终要做的事情。不过,我只是想知道,是否有人以前做过类似的事情并提出了一个巧妙的解决方案。
Boost.Program_options 提供了一种通过命令行参数传递多个令牌的工具,如下所示:
std::vector<int> nums;
po::options_description desc("Allowed options");
desc.add_options()
("help", "Produce help message.")
("nums", po::value< std::vector<int> >(&nums)->multitoken(), "Numbers.")
;
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
Run Code Online (Sandbox Code Playgroud)
但是,只接受固定数量参数的首选方式是什么?我能来的唯一解决方案是手动分配值:
int nums[2];
po::options_description desc("Allowed options");
desc.add_options()
("help", "Produce help message.")
("nums", "Numbers.")
;
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
if (vm.count("nums")) {
// Assign nums
}
Run Code Online (Sandbox Code Playgroud)
这感觉有点笨拙。有更好的解决方案吗?
boost::program_options 的 options_description 匹配的完成方式似乎存在问题。
int main(int argc, char* argv[])
{
boost::program_options::options_description desc("CmdLine utility");
desc.add_options()
("hel", "hel message")
("help", "produce help message")
("helps","helps message")
;
boost::program_options::variables_map vm;
boost::program_options::store(boost::program_options::parse_command_line(argc, argv,desc), vm);
boost::program_options::notify(vm);
if(vm.count("help")) {
std::cout << desc << std::endl;
}
if(vm.count("helps")) {
std::cout << "helps..." << std::endl;
}
if(vm.count("hel")) {
std::cout << "hel..." << std::endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出 -
C:\code>cmd.exe --helps
helps...
C:\code>cmd.exe --help
helps...
C:\code>cmd.exe --hel
helps...
Run Code Online (Sandbox Code Playgroud)
如果我更改使用 call 添加选项的顺序,输出会发生变化add_options()。另外,program_options 似乎没有进行完整的命令字符串匹配,因此即使您输入选项的子字符串,它也会将其视为有效选项,而不进行完整的字符串比较。如果这是 boost::program_options 功能,是否有任何方法可以强制它进行精确的字符串匹配,而不是使用子字符串匹配?(我使用的是Boost版本1.42)
c++ windows boost command-line-arguments boost-program-options
*强调文本*如何使用 Boost 程序选项从命令行接受单字节变量?
--id1=1 --id2=1结果的命令行参数为id1=49(或 '1', 0x31)和 id2=1。
#include <stdint.h>
#include <iostream>
#include <boost/program_options.hpp>
using namespace std;
int main(int argc, char** argv)
{
(void)argc;
(void)argv;
namespace po = boost::program_options;
const int myargc = 3;
const char* myargv[] = {"foo","--id1=1","--id2=2" };
uint8_t id1;
uint16_t id2; // works as expected.
po::variables_map vm;
po::options_description cmd_options( "Command options" );
cmd_options.add_options()
( "id1", po::value<uint8_t >( &id1 )->default_value( 0 ), "A 1-byte ID" )
( "id2", po::value<uint16_t>( &id2 )->default_value( 0 ), "A 2-byte ID" ) …Run Code Online (Sandbox Code Playgroud) 使用bool_switch,我可以编写一个命令行选项来打开一个标志:
bool flag;
po::options_description options;
options.add_options()
("on", po::bool_switch(&flag)->default_value(false))
;
Run Code Online (Sandbox Code Playgroud)
哪里现在./a.out将有flag==false和./a.out --on将有flag==true。但是,对于被明确的目的,我会像另外添加一个命令行选项来把标志关闭。就像是:
options.add_options()
("on", po::bool_switch(&flag)->default_value(false))
("off", po::anti_bool_switch(&flag)) // ????
;
Run Code Online (Sandbox Code Playgroud)
有没有办法anti_bool_switch在 program_options 库中做,或者我基本上必须编写代理 bool 引用?
我们目前正在调查我们程序中可能的未定义行为,该行为由 clang7 UBSan 与 boost 1.69.0 中的 boost::program_option 结合标记。我们已经创建了以下可以编译和运行的工作示例clang++ -std=c++17 -fsanitize=undefined -fno-omit-frame-pointer -lboost_program_options debug.cpp && UBSAN_OPTIONS=print_stacktrace=1 ./a.out
#include <iostream>
#include <boost/program_options.hpp>
namespace po = boost::program_options;
int main() {
std::string test_string = "";
po::options_description desc("test");
desc.add_options()
("string", po::value<std::string>(&test_string))
;
constexpr char *argv[] = {"test", "--string", "test"};
constexpr int argc = sizeof(argv) / sizeof(char*);
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
std::cerr << "Before notify" << std::endl;
po::notify(vm);
std::cout << "string -> " << test_string << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我们得到以下输出:
/usr/include/boost/any.hpp:249:17: runtime error: …Run Code Online (Sandbox Code Playgroud) 我有一个boost::program_options::variables_map参数。现在我想像键值对一样手动插入到这个地图中。例子:
boost::program_options::variables_map args
args["document"] = "A";
args["flag"] = true;
Run Code Online (Sandbox Code Playgroud)
问题是我已经有了这两个选项
desc.add_options()
("document", po::value<std::string>())
("flag", po::value<bool>());
Run Code Online (Sandbox Code Playgroud)
但有时它们会从命令行获得空输入。所以如果它们是空的,那么我必须在 po::variables_map args 本身中更新它们
有没有办法改变boost :: program_options如何格式化a的帮助文本中的选项的默认值program_options::options_description(可以获得cout << description)?特别是我有默认值浮点数,所以通常的十进制到二进制转换给我一个看起来--arg (0.100000001)很难看的帮助文本.
使用cout << setprecision(4),因为program_options是不工作<<"荷兰国际集团本身的默认值一些内部流先做格式(至少这是我通过查看源代码推断),以及是什么鬼<<"版到cout是生成的字符串(流?).
谢谢.
我有以下boost :: program_options程序.
boost::program_options::options_description opts("Allowed options");
opts.add_options()
("help", "produce help message"),
("mingw", boost::program_options::value<std::string>(), "Set the install path for MinGW"),
("triple", boost::program_options::value<std::string>(), "Set the target triple"),
("output", boost::program_options::value<std::string>(), "Set the output file"),
("input", boost::program_options::value<std::vector<std::string>>(), "Set an input file."),
("include", boost::program_options::value<std::vector<std::string>>(), "Set an include path.")
;
boost::program_options::positional_options_description posopts;
posopts.add("input", -1);
boost::program_options::variables_map vm;
try {
boost::program_options::store(boost::program_options::command_line_parser(argc, argv).options(opts).positional(posopts).run(), vm);
} catch(std::exception& e) {
std::cout << e.what();
std::cin.get();
}
boost::program_options::notify(vm);
if (vm.find("help") != vm.end()) {
std::cout << opts << "\n";
std::cin.get();
return 1;
}
// …Run Code Online (Sandbox Code Playgroud)