Chinaunix首页 | 论坛 | 博客
  • 博客访问: 623517
  • 博文数量: 116
  • 博客积分: 6078
  • 博客等级: 准将
  • 技术积分: 1214
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-23 10:09
文章分类

全部博文(116)

文章存档

2016年(1)

2015年(4)

2011年(2)

2010年(21)

2009年(88)

分类: C/C++

2009-12-08 21:55:43

命令行处理是另一个难点,开发人员通常不会采用结构化的方式来解决。其结果是从头到尾维护开销。Boost program_options 库提供了简化命令行处理的例程和数据结构。

清单 15 详细描述了 boost::program_options 的使用。这是建议在您的代码中使用的标准模板。



                
#include
#include
#include
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(),
"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;
}

return 0;
}

您必须包括 program_options.hpp 头文件。清单 15 的工作方式如下:

  1. options_description 类声明所有的有效命令行选项。
  2. 使用方法 add_options,您可以注册命令和跟在命令后面的参数类型。在此例中,help 选项不需要任何参数,但是 file 选项需要一个字符串参数。
  3. variables_map 类在运行时存储命令行选项及其参数。
  4. Boost 的 parse_command_line 例程解析 argcargv 参数。storenotify 方法帮助存储 vmap 对象中的数据。
  5. 当您检查 help 是否为程序的恰当命令行选项(这是 vmap.count("help") 所做的工作)时,options 对象将被转储到 cout。这意味着运算符 << 是为 options_description 类定义的。

下面是来自清单 15 的输出:

[user@/home/user1] ./a.out --help
command line options:
--help Use -h or --help to list all arguments
--file arg Provide input file name

当您遇到其他选项时,可以采取进一步的操作。例如,下面的代码片段经过了修改,以打印您输入的文件名:


if (vmap.count("file")) {
cout << "Setting input file to " << vmap["file"].as() << ".\n";
} else {
cout << "No file specified\n";
}


请注意,variable_map 类在许多方面与哈希表非常相似。例如,要检索 file 参数,您可以调用 vmap["file"]





回页首


命令行处理通常同时需要同一个命令选项的短名称和长名称。此外,您通常必须多次使用某个选项,以便收集该选项的所有参数。例如,您可能希望使用 ¨Ch¨Chelp 来打印可用的命令。清单 16 演示了这些功能。



                
#include
#include
#include
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 >( ),
"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 ifiles(vmap["file"].as< vector > ());
vector::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 选项现在是使用一个字符串向量来定义的。如果指定了 ¨Cfile 选项多次,则会将在所有指定中收集到的命令选项参数存储在关联的 vector 中。下面是使用不同的参数来多次指定 ¨Ch¨Cfile 所获得的输出:

[user@/home/user1] ./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
[user@/home/user1] ./a.out --file abc --file pqr
Number of input files: 2
Input file list:
abc
pqr





回页首


带输入参数但是不带命令行选项来调用某个程序是非常普遍的。您预期参数和命令行选项之间自动存在某种神奇关联。这种行为由 boost::program_options 提供支持。

请考虑清单 17。第一个参数转换为 --file=,第二个参数转换为 --do-file=



                
#include
#include
#include
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(),
"Provide input file name")
("do-file", boost::program_options::value(),
"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 ( ) << endl;
}

if (vmap.count("do-file")) {
cout << "do-file: " << vmap["do-file"].as ( ) << endl;
}

return 0;
}

下面是输出内容:

[user@/home/user1] ./a.out file1 dofile1
file: file1
do-file: dofile1

清单 15 中使用的某些 API 在清单 17 中已发生更改。清单 17 引入了新的类 positional_options_description。该类的 add 方法(add("command option", N))将位置 N 处的输入参数与命令行选项 "command option" 相关联。因此,./a.out file1 在内部解析为 ./a.out ¨Cfile=file1。另一个区别在于调用 program_options::store 方法的方式。与使用 parse_command_line 例程不同,Boost 库要求您将 command_line_parser 例程与 store 方法结合在一起使用。

请注意,仍然可以使用 ¨Cfile¨Cdo-file 选项来调用该程序。最后,若要将所有的输入参数与同一个命令行选项相关联,您需要使用值 -1 将该命令行选项添加到 positional_options_description 对象。下面是代码:


boost::program_options::positional_options_description poptd;
poptd.add("file", -1);
...





回页首

阅读(2374) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~