从命令行提取程序运行时选项的方法有很多。你可以自己编写相对应的完整的解析函数,或许你有丰富的C语言编程经验,熟知getopt()函数的用法,又或许使用Python的你已经在使用optparse库来简化这一工作。
program_options 提供程序员一种方便的命令行和配置文件进行程序选项设置的方法。使用program_options库而不是你自己动手写相关的解析代码,因为它更简单,声明程序选项的语法简洁,并且库自身也非常小。将选项值转换为适合的类型值的工作也都能自动完成。库有着完备的错误检查机制,如果自己手写解析代码时,就可能会错过对一些出错情况的检查了。最后,选项值不仅能从命令行获取,也能从配置文件,甚至于环境变量中提取,而这些选择不会增加明显的工作量。1. 首先看一个简单的程序吧:
#include <string>
#include <iostream>
#include <boost/program_options.hpp>
using namespace std;
int main (int ac, char* av[])
{
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(ac, av, 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;
}
//compile: g++ boost_test.cpp -o boost_test -lboost_program_options
|
程序的工作方式如下:
options_description
类声明所有的有效命令行选项。- 使用方法
add_options
,您可以注册命令和跟在命令后面的参数类型。在此例中,help
选项不需要任何参数,但是 file
选项需要一个字符串参数。 variables_map
类在运行时存储命令行选项及其参数。- Boost 的
parse_command_line
函数解析 argc
和 argv
参数。store
和 notify
方法帮助存储 vmap
对象中的数据。 - vmap.count()用于检测输入的是哪个命令行参数,并采取适当的动作
命令行处理通常同时需要同一个命令选项的短名称和长名称。此外,您通常必须多次使用某个选项,以便收集该选项的所有参数。例如,您可能希望使用 -h
和 --help
来打印可用的命令:
#include <string>
#include <iostream>
#include <boost/program_options.hpp>
using namespace std;
int main (int ac, char* av[])
{
boost::program_options::options_description options("command line options");
options.add_options() ("help,h", "Use -h or --help to list all arguments")
("file", boost::program_options::value<vector<string> >( ),
"Provide input file name");
boost::program_options::variables_map vmap;
boost::program_options::store(
boost::program_options::parse_command_line(ac, av, options), vmap);
boost::program_options::notify(vmap);
if (vmap.count("help")) {
cout << options << endl;
}
if (vmap.count("file")) {
vector<string> ifiles(vmap["file"].as< vector<string> > ());
vector<string>::iterator vI;
cout << "Number of input files: " << ifiles.size() << endl;
cout << "Input file list: " << endl;
for(vI = ifiles.begin(); vI != ifiles.end(); ++vI)
cout << "\t" << *vI << endl;
} else {
cout << "No file specified\n";
}
return 0;
}
|
在使用 add_options
来添加命令选项时,较长和较短的选项之间使用逗号进行分隔。请注意,较长的选项 (help
) 必须在较短的选项 (h
) 之前,代码才能正常工作。与使用单个字符串不同,file
选项现在是使用一个字符串向量来定义的。如果指定了 --file
选项多次,则会将所有收集到的file命令选项参数存储在关联的vector
中。下面是使用不同的参数来多次指定 --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
|
下面的程序,第一个参数转换为 --file=
,第二个参数转换为 --do-file=
。
#include <string>
#include <iostream>
#include <boost/program_options.hpp>
using namespace std;
int main (int ac, char* av[])
{
boost::program_options::options_description options("command line options");
options.add_options() ("help,h", "Use -h or --help to list all arguments")
("file", boost::program_options::value<string>(),
"Provide input file name")
("do-file", boost::program_options::value<string>(),
"Specify commands file");
boost::program_options::variables_map vmap;
boost::program_options::positional_options_description poptd;
poptd.add("file", 1);
poptd.add("do-file", 2);
boost::program_options::store(
boost::program_options::command_line_parser(ac, av).
options(options).positional(poptd).run(), vmap);
boost::program_options::notify(vmap);
if (vmap.count("file")) {
cout << "file: " << vmap["file"].as<string> ( ) << endl;
}
if (vmap.count("do-file")) {
cout << "do-file: " << vmap["do-file"].as<string> ( ) << endl;
}
return 0;
}
|
下面是输出内容:
./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); ... |
阅读(1826) | 评论(0) | 转发(0) |