program options是一系列pair<name,value>
组成的选项列表,它允许程序通过命令行或配置文件来读取这些参数选项.
program_options的使用主要通过下面三个组件完成:
-
代码流程总览
-
示例
#include <iostream>
#include <boost/program_options.hpp>
using namespace std;
namespace po = boost::program_options;
int main(int argc, const char * argv[])
{
try {
po::options_description desc("选项");
desc.add_options()
("help", "print help messages")
("name",po::value<string>(), "the name")
("age",po::value<int>(), "the age")
;
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
if (vm.count("help")) {
cout << desc << "\n";
return 0;
}
if (vm.count("name")) {
cout << "The Name: " << vm["name"].as<string>() << ".\n";
} else {
cout << desc << "\n";
return -1;
}
if(vm.count("age")){
cout << "The Age: " << vm["age"].as<int>() << "\n";
} else {
cout << desc << "\n";
return -1;
}
}
catch(exception &e) {
cerr << "error: " << e.what() << "\n";
return 1;
}
catch(...) {
cerr << "Exception of unknow type!\n";
}
return 0;
}
运行结果:
$ g++ options.cpp -lboost_program_options-mt -I /opt/local/include/ -L /opt/local/lib/ -o options
or
$ g++ options.cpp /opt/local/lib/libboost_program_options-mt.a -I /opt/local/include/ -o options
$ ./options
选项:
--help print help messages
--name arg the name
--age arg the age
$ ./options --name "Leslie Zhu" --age 25
The Name: Leslie Zhu.
The Age: 25
$ ./options --name "Leslie Zhu" --age "25"
The Name: Leslie Zhu.
The Age: 25
$ ./options --name "Leslie Zhu" --age "25" --what "the fox say?"
error: unrecognised option '--what'
-
普通选项
// Declare the supported options.
po::options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("compression", po::value<int>(), "set compression level")
;
po::variables_map vm;
po::store(po::parse_command_line(arc, argv, desc), vm);
po::notify(vm);
if (vm.count("help")) {
cout << desc << "\n";
return 1;
}
if (vm.count("compression")) {
cout << "Compression level was set to "
<< vm["compression"].as<int>() << ".\n";
} else {
cout << "Compression level was not set.\n";
}
- 创建
类options_description
的对象 - 调用
add_options
来添加选项 - 创建
类variables_map
对象 - 调用
parse_command_line
来将参数选项等保存到variables_map对象 - 调用notify函数
- 之后可以参数map一样操作variables_map对象
- 通过调用as函数来获取参数值
-
默认值
string name;
int age;
try {
po::options_description desc("选项");
desc.add_options()
("help", "print help messages")
("name",po::value<string>(), "the name")
("age",po::value<int>(&age)->default_value(18), "the age")
;
这里通过 &age
来指定默认值。
运行效果:
$ g++ options.cpp /opt/local/lib/libboost_program_options-mt.a -I /opt/local/include/ -o options_v3
$ ./options_v3
./options_v3
选项:
--help print help messages
--name arg the name
--age arg (=18) the age
$ ./options_v3 --name "Leslie"
The Name: Leslie.
The Age: 18
-
多选项
#include <iostream>
#include <boost/program_options.hpp>
using namespace std;
namespace po = boost::program_options;
template<class T>
ostream& operator<<(ostream& os, const vector<T>& v)
{
copy(v.begin(), v.end(), ostream_iterator<T>(os, " "));
return os;
}
int main(int argc, const char * argv[])
{
string name;
int age;
try {
po::options_description desc("选项");
desc.add_options()
("help", "print help messages")
("name",po::value<string>(), "the name")
("age",po::value<int>(&age)->default_value(18), "the age")
("include-path,I", po::value< vector<string> >(), "include path")
;
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
if (vm.count("help")) {
cout << desc << "\n";
return 0;
}
if (vm.count("name")) {
cout << "The Name: " << vm["name"].as<string>() << ".\n";
} else {
cout << desc << "\n";
return -1;
}
if(vm.count("age")){
cout << "The Age: " << vm["age"].as<int>() << "\n";
} else {
cout << desc << "\n";
return -1;
}
if(vm.count("I") || vm.count("include-path")) {
cout << "The include-path: " << vm["include-path"].as< vector<string> >() << "\n";
} else {
cout << desc << "\n";
return -1;
}
}
catch(exception &e) {
cerr << "error: " << e.what() << "\n";
return 1;
}
catch(...) {
cerr << "Exception of unknow type!\n";
}
return 0;
}
这里因为选项值保存不是int或string类型,因此重载了 <<
操作符。
template<class T>
ostream& operator<<(ostream& os, const vector<T>& v)
{
copy(v.begin(), v.end(), ostream_iterator<T>(os, " "));
return os;
}
$ g++ options.cpp /opt/local/lib/libboost_program_options-mt.a -I /opt/local/include/ -o options_v4
$ ./options_v4
选项:
--help print help messages
--name arg the name
--age arg (=18) the age
-I [ --include-path ] arg include path
$ ./options_v4 --name Leslie -I ~
The Name: Leslie.
The Age: 18
The include-path: /Users/LeslieZhu
$ ./options_v4 --name Leslie --include-path ~
The Name: Leslie.
The Age: 18
The include-path: /Users/LeslieZhu
$ ./options_v4 --name Leslie --include-path ~ -I ~/Applications/
The Name: Leslie.
The Age: 18
The include-path: /Users/LeslieZhu /Users/LeslieZhu/Applications/
$ ./options_v4 --name Leslie --include-path ~ -I ~/Applications/ -I ~/Library/
The Name: Leslie.
The Age: 18
The include-path: /Users/LeslieZhu /Users/LeslieZhu/Applications/ /Users/LeslieZhu/Library/
-
位置选项
po::options_description desc("选项");
desc.add_options()
("help", "print help messages")
("name",po::value<string>(), "the name")
("age",po::value<int>(&age)->default_value(18), "the age")
("include-path,I", po::value< vector<string> >(), "include path")
("input-file", po::value< vector<string> >(), "input file")
;
po::positional_options_description p;
p.add("input-file", -1);
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
po::notify(vm);
位置选项:
$./options_v5 --name Leslie -I ~ --input-file=options.cpp
The Name: Leslie.
The Age: 18
The include-path: /Users/LeslieZhu
Input files are: options.cpp
$./options_v5 --name Leslie -I ~ --input-file options.cpp
The Name: Leslie.
The Age: 18
The include-path: /Users/LeslieZhu
Input files are: options.cpp
$./options_v5 --name Leslie -I ~ options.cpp
The Name: Leslie.
The Age: 18
The include-path: /Users/LeslieZhu
Input files are: options.cpp
-
多个输入选项
po::options_description generic("Generic options");
generic.add_options()
("version,v", "print version string")
("help", "produce help message")
("config,c", po::value<string>(&config_file)->default_value("multiple_sources.cfg"),
"name of a file of a configuration.")
;
// Declare a group of options that will be
// allowed both on command line and in
// config file
po::options_description config("Configuration");
config.add_options()
("optimization", po::value<int>(&opt)->default_value(10),
"optimization level")
("include-path,I",
po::value< vector<string> >()->composing(),
"include path")
;
// Hidden options, will be allowed both on command line and
// in config file, but will not be shown to the user.
po::options_description hidden("Hidden options");
hidden.add_options()
("input-file", po::value< vector<string> >(), "input file")
;
po::options_description cmdline_options;
cmdline_options.add(generic).add(config).add(hidden);
po::options_description config_file_options;
config_file_options.add(config).add(hidden);
po::options_description visible("Allowed options");
visible.add(generic).add(config);
po::positional_options_description p;
p.add("input-file", -1);
po::variables_map vm;
store(po::command_line_parser(ac, av).
options(cmdline_options).positional(p).run(), vm);
notify(vm);
这段合并选项:
po::options_description cmdline_options;
cmdline_options.add(generic).add(config).add(hidden);
po::options_description config_file_options;
config_file_options.add(config).add(hidden);
po::options_description visible("Allowed options");
visible.add(generic).add(config);
store(po::command_line_parser(ac, av).
options(cmdline_options).positional(p).run(), vm);
运行效果:
$ ./run --help
Allowed options:
Generic options:
-v [ --version ] print version string
--help produce help message
-c [ --config ] arg (=multiple_sources.cfg)
name of a file of a configuration.
Configuration:
--optimization arg (=10) optimization level
-I [ --include-path ] arg include path
-
后记
大致看了看源码,目前来说,很多地方还不是很理解。但这个库功能还是非常强大的。
- 基本的选项解析
- 复杂的选项解析
- 配置文件的解析
- 环境变量的解析
- 自定义选项格式
-
参考