boost -- program_options

program_options 是一个实现了类似 optarg 但是比 optargs 功能强大的 boost库.
使用它来解析命令行参数或者配置文件都是很简单的.
官方教程

http://www.boost.org/doc/libs/1_57_0/doc/html/program_options.html

依赖
安装boost库, 至少编译 program_options 部分.
添加include路径

-I boost_include_path

添加链接库

-lboost_program_options

头文件 命名空间

#include "boost/program_options.hpp"
using namespace  boost::program_options;

简单操作
定义并添加命令说明

int opt;
/* 类 options_description 是存储选项详细信息的类 */
options_description parser("name_your_like");
/*add_option() 支持() 操作. 多次调用add_options() 的效果等同于将所有的选项使用() 并列声明*/
parser.add_options()
         /*无参数的选项格式 : "命令名" , "命令说明" */
         ("help", "produce help message")
         /* 有参赛的选项格式 : 
          "命令名" , "参数说明" , "命令说明" */ 
         ("set-float" ,value<float>(), "set a float parameter")
         /* 参数对应已有数据(特定地址) , 并且有初始值 : */ 
         ("optimization", value<int>(&opt)->default_value(10), 
             "optimization level")
         /* 支持短选项 ( --include-path 和 -I 等效 ) ,
            多次调用存在依次vector中 */
         ("include-path,I", value< vector<string> >(), 
             "include path")
        ;

解析命令行 , 存储在variables_map 类的变量中

/* variables_map 类是用来存储具体传入参数数据的类 , 和map很相似. 使用as接口来传出数据 */
variables_map vm;
/* ac 就是参数个数 , av 就是参数列表指针 */
/* int ac , const char ** av */
/* parse_command_line 接口不支持猜测选项 */
store(parse_command_line(ac, av, desc), vm);
notify(vm);    

注意: 如果传入没有定义的选项, 会抛出异常!
判断命令是否触发 , 以 help 为例

/* variables_map 使用 count 接口来判断具体选项是否触发 */
if (vm.count("help")) {
   /*如果触发就输出命令说明 , option_description 类重载了 << 行为, 将格式化的输出
   命令说明 */
    cout << desc << "\n";
    return 1;
}

取出传入的参数 , 以上面的float参数为例

首先, 如果已经指定了一个接受数据 [ 比如 : (“optimization”, value(&opt)->default_value(10), “optimization level”) ]的话,就可以直接使用它.

if (vm.count("set-float")) {
    cout << "set-float "<<
    /*map直接使用键值当index , 然后使用as< 具体类型> 接口来取出参数*/ 
    vm["set-float"].as<float>() << ".\n";
} else {
    cout << "float not set\n";
}

定义默认参数.

上面的例子中 ,如下操作:

$ a.out –set-float=0.131415926
$ set-float 0.131415926

然而假设我们想要以下面的命令实现上面的效果:

$ a.out 0.131415926
$ set-float 0.131415926

就需要设置set-float 为默认的参数.

int opt;
options_description parser("name_your_like");
parser.add_options()
         ("help", "produce help message")
         ("set-float" ,value<float>(), "set a float parameter")
         ("optimization", value<int>(&opt)->default_value(10), 
             "optimization level")
         ("include-path,I", value< vector<string> >(), 
             "include path")
        ;
/* 定义一个可以猜测的命令 positional_options_description */
positional_options_description p;
/* 指定猜测的时候参数的位置, -1 标识没有任何限制 */
p.add("set-float", -1);

variables_map vm;
/* 使用可以猜测的命令行解析接口来解析 */
store(command_line_parser(ac, av).options(desc).positional(p).run(), vm);
notify(vm);  

这样就支持了默认选项是 –set-float
对配置文件的支持

 /*将文件读入流*/
 ifstream ifs("file_name");
 /* 调用解析文件接口 */
 store(parse_config_file(ifs, desc), vm);
 notify(vm); 

下面是一个例子

    boost::program_options::positional_options_description arguments;
    arguments.add("type", 1);
    arguments.add("connect", 1);

    boost::program_options::options_description all;
    all.add_options()
        ( "type", "0mq socket type" )
        ;
    all.add(miscellaneous_options());
    all.add(connection_options());

    boost::program_options::variables_map vm;
    client_options options;

    try
    {
        boost::program_options::store( boost::program_options::command_line_parser( argc, argv ).options( all ).positional( arguments ).run(), vm );
    }
    catch(boost::program_options::too_many_positional_options_error& e)
    {
        std::cerr << "Too many arguments provided." << std::endl;
        options.show_usage = true;
    }
    catch(boost::program_options::unknown_option& e)
    {
        std::cerr << "Unknown option '" << e.get_option_name() << "'." << std::endl;
        options.show_usage = true;
    }
    catch(boost::program_options::error& e)
    {
        std::cerr << "command line parse error: " << e.what() << "'." << std::endl;
        options.show_usage = true;
    }

    socket_type_index socket_types = socket_type_options();
    if ( vm.count( "type" ) && ( socket_types.end() == socket_types.find( vm["type"].as<std::string>() ) ) )
    {
        std::cerr << "Unknown value '" << vm["type"].as<std::string>() << "' provided for 0mq socket type." << std::endl;
        options.show_usage = true;
    }

    if ( (0 == vm.count( "type" )) || vm.count( "help" ) || ( (0 == vm.count( "connect" )) && (0 == vm.count( "bind" )) ) )
    {
        options.show_usage = true;
    }

    options.show_version = ( vm.count( "version" ) > 0 );
    options.show_help = ( vm.count( "help" ) > 0 );

    if ( vm.count( "type" ) )    { options.type     = socket_types[ vm["type"].as<std::string>() ]; }
    if ( vm.count( "bind" ) )    { options.binds    = vm["bind"].as<std::vector<std::string>>(); }
    if ( vm.count( "connect" ) ) { options.connects = vm["connect"].as<std::vector<std::string>>(); }

    options.singlepart = ( vm.count( "singlepart" ) > 0 );

    options.annotate = ( vm.count( "annotate" ) > 0 );
    options.verbose = ( vm.count( "verbose" ) > 0 || vm.count( "detailed" ) > 0 );
    options.detailed = ( vm.count( "detailed" ) > 0 );
    options.exit_on_empty = ( vm.count( "exit-when-no-input" ) > 0 );

    return options;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值