c++11 boost 命令行参数解析 program_options

2018-07-13 15:33:03

program_options 库可以解析命令行参数,功能强大。标准 c 里也有可以解析的,相对简单点,读者可以参考 linux c解析命令行选项getopt

想要使用 program_options 库编译的时候记得带上 -lboost_program_options 免得报找不到特定函数。

undefined reference to `boost::program_options::options_description::add_options
// Copyright (c) 2015
// Author: Chrono Law
#include <fstream>
#include <sstream>
#include <iostream>
using namespace std;

#include <boost/program_options.hpp>
using namespace boost::program_options;

int case1(int argc, char* argv[])
{
    options_description opts("demo options");

    opts.add_options()
        ("help", "just a help info")
        ("filename", value<string>(), "to find a file")
        ;
    variables_map vm;
    
    //解析命令行参数并存储到 vm里
    store(parse_command_line(argc, argv, opts), vm);

	//--help 输出描述
    if (vm.count("help"))
    {
        cout << opts << endl;
        return 0;
    }

	//--filename tmp.txt
    if (vm.count("filename"))
    {   cout << "find " << vm["filename"].as<string>() << endl;}

    if (vm.empty())
    {   cout << "no options" << endl;   }

    return 0;
}

void case2()
{
    value<string>();

    value<int>()->default_value(10)
        ->implicit_value(1);         //默认值是10,隐含值是1

    double x;
    value<double>(&x)->zero_tokens()  //必须提供,可以由0个或多个记号
        ->multitoken()->required();

}

//打印
void print_vm(options_description &opts, variables_map &vm)
{
	//空或 --help 都打印描述信息
    if (vm.empty())
    {
        cout << opts << endl;
        return;
    }

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

    //输出查找文件名,因为它有缺省值,故总存在
    cout << "find opt:" << vm["filename"].as<string>() << endl;

	//打印出多个dir指定的
    if (vm.count("dir"))
    {
        cout << "dir opt:";
        for(auto& str:
                vm["dir"].as<vector<string> >())
        {   cout << str << ","; }
        cout << endl;
    }

	//深度
    if (vm.count("depth"))
    {   cout << "depth opt:" << vm["depth"].as<int>() << endl;}
}

//
void case3(int argc, char* argv[])
{
    options_description opts("demo options");

    string filename;
    int depth;
    
    //用逗号隔开,前面是长名称 --help,后面是短名称 -h
    opts.add_options()

        ("help,h", "help message\n   a bit of long text")

        ("filename,f",
         value<string>(&filename)->default_value("test"), "to find a file")  //默认为 test

        ("dir,D", value<vector<string> >()->multitoken(), "search dir")  //指定多个

        ("depth,d", value<int>(&depth)->implicit_value(5), "search depth")    //描述显示为5
        ;

    variables_map vm;
    store(parse_command_line(argc, argv, opts), vm);
    
    //更新外部变量,也就是把值存入filename,depth
    notify(vm);
    cout << filename << " " << depth << endl;

    print_vm(opts, vm);

	//也可以从配置文件解析
    stringstream ss;
    ss << "filename=a.cpp\ndir=/usr/bin\ndepth=10";
    store(parse_config_file(ss, opts), vm);

    ifstream ifs("config.ini");
    store(parse_config_file(ifs, opts, true), vm);

    const char *str = "config.ini";
    store(parse_config_file<char>(str, opts, true), vm);

}

//位置选项
void case4(int argc, char* argv[])
{
    options_description opts("demo options");

    string filename;
    opts.add_options()

        ("help,h", "help message\n   a bit of long text")

        ("filename,f",
         value<string>(&filename)->default_value("test"), "to find a file")

        ("dir,D", value<vector<string> >()->multitoken(), "search dir")

        ("depth,d", value<int>()->implicit_value(5), "search depth")
        ;

    variables_map vm;

	//这里增加了位置选项,1代表1个,2代表2个,-1代表不指定,默认为1
	// ./a.out tmp.txt tmp ext 2
    positional_options_description pod;
    pod.add("filename", 1).add("dir", 2).add("depth", -1);
    
    auto pr =
        command_line_parser(argc, argv).
            options(opts).
                positional(pod).
                    run();
    store(pr, vm );

    notify(vm);
    print_vm(opts, vm);
}

//名称映射
string name_mapper(const string& env_name)
{
    static map<string, string> nm =
        {{"HOME", "home"},{"USER", "uname"}};

    return nm[env_name];
}

//从环境变量里解析
void case5(int argc, char* argv[])
{
    options_description opts("demo options");

    string filename;
    opts.add_options()

        ("help,h", "help message\n   a bit of long text")

        ("filename,f",
         value<string>(&filename)->default_value("test"), "to find a file")

        ("dir,D", value<vector<string> >()->multitoken(), "search dir")

        ("depth,d", value<int>()->implicit_value(5), "search depth")
        ("home", value<string>(), "home dir")
        ("uname", value<string>(), "user's name")

        ;

    variables_map vm;

    store(parse_environment(opts, name_mapper),vm);
    cout << vm["home"].as<string> ()<< endl;
    cout << vm["uname"].as<string> ()<< endl;

    notify(vm);
    print_vm(opts, vm);
}

//分组选项
void case6(int argc, char* argv[])
{
    options_description opts1("group 1");
    opts1.add_options()
        ("help,h", "help message");

    options_description opts2("group 2(hide)");
    opts2.add_options()
        ("filename,f", value<string>(), "to find a file");

    options_description opts3("group 3");
    opts3.add_options()
        ("dir,D", value<vector<string> >()->composing(), "search dir")
        ("depth,d", value<int>(), "search depth");

    options_description opts_all;
    opts_all.add(opts1).add(opts2).add(opts3);

    options_description opts_cfgfile;
    opts_cfgfile.add(opts2).add(opts3);

    options_description opts_showhelp("demo options");
    opts_showhelp.add(opts1).add(opts3);

    variables_map vm;

    store(parse_command_line(argc, argv, opts_all), vm);
    store(parse_config_file<char>("config.ini", opts_cfgfile, true), vm);

    if (vm.count("help") || vm.empty())
    {
        cout << opts_showhelp << endl;
        return;
    }

    notify(vm);
    print_vm(opts_all, vm);
}

int main(int argc, char* argv[])
{
    //case1(argc, argv);
    //case2();
    //case3(argc, argv);
    //case4(argc, argv);
    //case5(argc, argv);
    case6(argc, argv);
}
[root@192 c++]# g++ -std=c++11 main.cpp -lboost_program_options -L /usr/local/lib/boost_1_65_1/
[root@192 c++]# ./a.out -h
demo options:

group 1:
  -h [ --help ]          help message

group 3:
  -D [ --dir ] arg       search dir
  -d [ --depth ] arg     search depth


 备注

1.编译器版本gcc4.8.5,运行环境centos7 64位
2.本文只做简单记录用,详细用法请参考 Boost Library,或者是罗剑锋的 boost程序库完全开发指南 书本
3..原文地址http://www.freecls.com/a/2712/b0


©著作权归作者所有
收藏
推荐阅读
简介
天降大任于斯人也,必先苦其心志。