Dec 15, 2010

boost program options

program options 允许命令行和文件
命令行接受如下三种参数形式,以及不带 para 的 positional parameter
--para=value
--para value
-p value
例如
gcc -I /inclue main.c
main.c 为 positional parameter

文件接受的形式为
para = value
注释以#开头
注意文件不能为 utf8 格式

一个参数,如果类型是 vector<> 可以设置多个 value,存在 vector 中。
命令行解析和文件解析不属于多次设置,算两次解析。一般先解析命令行,则如果同一个参数在命令行中和文件中都出现,命令行中的有效,如此保证命令行优先级比较高。
以上的例外是,vector 且调用 composing 函数,则为融合。

positional 是附加选择,必选先定义参数,再将此参数定义为 positional
positional 也可以通过前面提到的命令行和文件形式赋值


例子,基本涵盖了平常的需求
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <boost/program_options.hpp>

using namespace std;
namespace po = boost::program_options;


void procImage(double scale, int level, const vector<string>& images)
{
 vector<string>::const_iterator iter;
 for(iter=images.begin();iter!=images.end();++iter)
 {
  cout << "Processing image " << *iter << " @ scale " << scale << ", level " << level
    << endl;
 }
}

int main(int ac, char * av[])
{
 po::options_description cfgdesc;

 //user defined parameters
 double scale;
 int level;
 //end
 
 
 string filename;

 //options for both command line and config file
 cfgdesc.add_options()
       ("scale,s",po::value<double>(&scale)->default_value(3.0),"scale")
       ("level,l",po::value<int>(&level)->default_value(2),"level")
       ("image,i",po::value<vector<string> >()->composing(),"Images");

 //positional options
 po::positional_options_description pdesc;
 pdesc.add("image",-1);

 //command line options
 po::options_description cmdline;
 cmdline.add_options()
       ("help,h","Show this message")
       ("config,c",po::value<string>(&filename),"Config File");
 cmdline.add(cfgdesc);


 po::variables_map vm;
 po::store(po::command_line_parser(ac,av).options(cmdline).positional(pdesc).run(),vm);
 po::notify(vm);

 ifstream cfgfile(filename.c_str());

 try
 {
  if(cfgfile)
  {
   po::store(po::parse_config_file(cfgfile,cfgdesc),vm);
   po::notify(vm);
  }

 }
 catch(exception &e)
 {
  cout << e.what() << endl;
 }

 if(vm.count("help"))
 {
  cout << cmdline << endl;
 }

 if(vm.count("image"))
 {
  procImage(scale, level, vm["image"].as<vector<string> >());
 }



 return 0;
}

0 comments: