Chinaunix首页 | 论坛 | 博客
  • 博客访问: 643819
  • 博文数量: 227
  • 博客积分: 8017
  • 博客等级: 中将
  • 技术积分: 2069
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-08 22:50
文章分类

全部博文(227)

文章存档

2011年(10)

2010年(55)

2009年(28)

2008年(134)

我的朋友

分类: C/C++

2011-01-09 18:24:22

从命令行提取程序运行时选项的方法有很多。你可以自己编写相对应的完整的解析函数,或许你有丰富的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 函数解析 argcargv 参数。storenotify 方法帮助存储 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) |
给主人留下些什么吧!~~