这是我研究图书馆 2 小时后可以实现的最佳答案。我将此作为答案发布,因为在某种程度上给出了问题的解决方案,但我知道很可能有人会提供更好的解决方案。
选择我们将使用哪个 options_description 对象解析命令行的最佳方法是什么?
到目前为止,我设法根据第一个选项在两个 options_description 对象之间进行选择(更多详细信息请参见代码)。我所做的如下:
- 创建两个 options_descrition 对象(
OptDescA 用于 TA 和 OptDescB 用于 TB)。
- 检查第一个参数是
command_a 还是command_b。
- 根据第一个参数,我使用
OptDescA 或OptDescB 解析命令行
对于第 3 点,我必须将 argc 减一并将 argv 指针 1 向前移动。
po::store(po::parse_command_line(argc - 1, argv + 1, OptDescA), vm);
这样我就不必在OptDescA 或OptDescB 中处理command_a 或command_b。
实现“命令”帮助系统的最佳方式是什么。
嗯,这是(实际上是)对我来说最困难的。实现细节参见下面的代码。
我的帮助系统的问题是我必须输入:
app help command_a
而不是最常见的:
app command_a help
除了你输入 app help 后,输出是:
Available commands:
--help arg Display this message
--command_a Do command_a stuff
--command_b Do command_b stuff
注意丑陋的--help arg
代码
#include <iostream>
#include <string>
#include <boost/program_options.hpp>
using namespace std;
void help_system(string target);
int main(int argc, char *argv[])
{
namespace po = boost::program_options;
po::options_description command_a("Command_a options");
command_a.add_options()
("option_1", po::value<int>()->required(), "option_1 desc")
("option_2", po::value<int>()->required(), "option_2 desc")
;
po::options_description command_b("Command_b options");
command_b.add_options()
("option_3", po::value<int>()->required(), "option_3 desc")
("option_4", po::value<int>()->required(), "option_4 desc")
;
po::options_description commands("Available commands");
commands.add_options()
("help", po::value<string>()->default_value(""), "Display this message")
("command_a", "Do command_a stuff")
("command_b", "Do command_b stuff")
;
po::variables_map vm;
if (string("command_a") == string(*(argv + 1))) {
try{ po::store(po::parse_command_line(argc - 1, argv + 1, command_a), vm); }
catch (exception &e){ cout << "Error: " << e.what() << endl; }
}
else if (string("command_b") == string(*(argv + 1))) {
try{ po::store(po::parse_command_line(argc - 1, argv + 1, command_b), vm); }
catch (exception &e){ cout << "Error: " << e.what() << endl; }
}
else if (string("help") == string(*(argv + 1)))
{
cout << commands << endl;
}
try { po::notify(vm); }
catch (exception &e) { cout << "Error: " << e.what() << endl; }
return 0;
}
void help_system(string target)
{
if (target.c_str() == "command_a") {} // The ideal is to do "cout << command_a" here
// but right now command_a is out of the scope.
if (target.c_str() == "command_b") {}
}