1、功能:用来完成命令行参数的解析工作。
由于C++标准库没有提供解析命令行参数的功能,在之前我们必须自己来完成解析工作。如果命令行参数很复杂,那么
正确解析命令行参数就不是件容易的事。boost库的program_options可以很好的完成这个功能。
2、program_options相对于手工编写代码解析命令行参数所具有的优点:
(1)使用更容易。定义参数处理的语法简单,库自身很小,像转换参数值到指定的类型和保存参数值到变量的事情都由
库自动处理。
(2)错误报告更友好,可以报告错误的命令行参数。另外这个库能自动生成使用帮助,避免手工更新使用帮助导致不一致。
(3)参数能从不同地方读取。当命令行参数不能满足我们要求时,可以改用配置文件。
3、用法:
(1)首先声明一个options_description类对象,该对象用于添加我们需要解析的选项的名字。
例:options_description myOptions("command line options by XXX");
int nLevel;
myOptions.add_options()("help,h", "Use --help or -h to list all arguments")
("file", value<string>(), "Provide input file name")
("level", value<int>(& nLevel)->default_value(5);
其中,长选项名(比如“help”)必须在前面,短选项名(比如“h“)可有也可没有,如果有,必须紧跟在逗号之后。另外,还可以给选项名赋默认值。
(2)添加好选项名字之后,就可以开始解析工作了。解析的结果保存在variables_map类型的对象中。
variables_map vmap;
// MFC中使用__argc和__argv
store(parse_command_line(argc, argv, myOptions), vmap);
notify(vmap);
其中,store函数可以调用多次,以将多个不同options_description的分析结果存入vmap中。
(3)调用解析后的参数值:
解析工作完成之后,解析的结果就保存在vmap中。我们现在可以从vmap中获取想要的选项值了。
if (vmap.count("help"))
{
cout << myOptions << endl; // 打印出使用帮助
}
if (vmap.count("file"))
{
cout << "file is " << vmap["file"].as<string> ( ) << endl;
}
cout << "level is " << nLevel << endl;
必须使用as来获得选项值;如果类型不符和,program_options会抛出异常。
4、看简单示例:
#include<string>
#include<iostream>
#include<boost/program_options.hpp>
using namespace std;
int main(int arc, char* agv[])
{
boost::program_options::options_description options("command line options");
options.add_options() ("help", "Use -h or --help to list all arguments")
("file", boost::program_options::value<string>(), "Provide input file name");
boost::program_options::variables_map vmap;
boost::program_options::store(boost::program_options::parse_command_line(arc, agv, options), vmap);
boost::program_options::notify(vmap);
if(vmap.count("help))
{
cout<<options<<endl;
}
if(vmap.count("file"))
{
cout<<"Your input file: "<<vmap["file"].as<string>() <<"\n";
}
return 0;
}
程序的工作方式如下:
options_description 类声明所有的有效命令行选项。
使用方法add_options, 你可以注册命令和跟在命令后面的参数类型。在此例中,help选项不需要任何参数,但是file选项
需要一个字符串参数。
variables_map类在运行时存储命令行选项及其参数。
boost的parse_command_line函数解析argc和argv参数。store和notify方法帮助存储vmap对象中的数据。
vmap.count()用于检测输入的是哪个命令行参数,并采取适当的动作
5、提供多个参数和缩写的命令选项。
命令行处理通常同时需要同一个命令选项的短名称和长名称。此外,你通常必须多次使用某个选项,以便收集该选项的
所有参数。例如,你可能希望使用-h和--help来打印可用的命令:
在使用add_options来添加命令选项时,较长和较短的选项之间使用逗号进行分隔。请注意,较长的选项(help)
必须在较短的选项(h)之前,代码才能正常工作。与使用单个字符串不同,file选项现在是使用一个字符串向量来定义
的。如果指定了--file选项多次,则会将所有收集到的file命令选项参数存储在关联的vector<string>中。下面是使用不同
的参数来多次指定--h和--file所获得的输出:
./a.out -h
command line options:
-h[ -- help ] Use -h or --help to list all arguments
--file arg Provide input file name
No file specified
./a.out --file abc --file pqr
Number of input files:2
Input file list:
abc
pqr
6、解析位置选项
下面的程序,第一个参数转换为 --file=<first parameter>, 第二个参数转换为 --do-file=<second parameter>.
下面是输出内容:
./a.out file1 dofile1
file: file1
do-file: dofile1
程序引入了新的类positional_options_description. 该类的add方法(add("command option", N))将位置N处的输入参数
与命令行选项“command option”相关联。因此,./a.out file1在内部解析为./a.out --file=file1.另一个区别在于调用
program_options::store方法的方式。与使用parse_command_line例程不同,boost库要求将command_line_parser
例程与store方法结合在一起使用。
注意:仍然可以使用--file和--do-file选项来调用该程序。最后,若要将所有的输入参数与同一个命令行选项相关联,需要
使用值-1将该命令行选项添加到positional_options_description对象。下面是代码:
boost::program_options::positional_options_description poptd;
poptd.add("file", -1);
...
(itlanger)