boost库学习③:program_options

program options是一系列pair<name,value>组成的选项列表,它允许程序通过命令行或配置文件来读取这些参数选项.

program_options的使用主要通过下面三个组件完成:

  •  代码流程总览

  • 示例

#include <iostream>
#include <boost/program_options.hpp>

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

int main(int argc, const char * argv[])
{
    try {
        po::options_description desc("选项");

        desc.add_options()
            ("help", "print help messages")
            ("name",po::value<string>(), "the name")
            ("age",po::value<int>(), "the age")
            ;

        po::variables_map vm;
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::notify(vm);

        if (vm.count("help")) {
            cout << desc << "\n";
            return 0;
        }

        if (vm.count("name")) {
            cout << "The Name: " << vm["name"].as<string>() << ".\n";
        } else {
            cout << desc << "\n";
            return -1;
        }

        if(vm.count("age")){
            cout << "The Age: " << vm["age"].as<int>()  << "\n";
        } else {
            cout << desc << "\n";
            return -1;
        }
    }

    catch(exception &e) {
        cerr << "error: " << e.what() << "\n";
        return 1;
    }

    catch(...) {
        cerr << "Exception of unknow type!\n";
    }

    return 0;
}

运行结果:

$ g++ options.cpp -lboost_program_options-mt -I /opt/local/include/ -L /opt/local/lib/ -o options

or

$ g++ options.cpp /opt/local/lib/libboost_program_options-mt.a -I /opt/local/include/  -o options


$ ./options
选项:
  --help                print help messages
  --name arg            the name
  --age arg             the age

$ ./options --name "Leslie Zhu" --age 25
The Name: Leslie Zhu.
The Age: 25

$ ./options --name "Leslie Zhu" --age "25"
The Name: Leslie Zhu.
The Age: 25

$ ./options --name "Leslie Zhu" --age "25" --what "the fox say?"
error: unrecognised option '--what'
  • 普通选项

// Declare the supported options.
po::options_description desc("Allowed options");
desc.add_options()
    ("help", "produce help message")
    ("compression", po::value<int>(), "set compression level")
;

po::variables_map vm;
po::store(po::parse_command_line(arc, argv, desc), vm);
po::notify(vm);    

if (vm.count("help")) {
    cout << desc << "\n";
    return 1;
}

if (vm.count("compression")) {
    cout << "Compression level was set to " 
 << vm["compression"].as<int>() << ".\n";
} else {
    cout << "Compression level was not set.\n";
}
  • 创建 类options_description 的对象
  • 调用 add_options 来添加选项
  • 创建 类variables_map 对象
  • 调用 parse_command_line 来将参数选项等保存到variables_map对象
  • 调用notify函数
  • 之后可以参数map一样操作variables_map对象
  • 通过调用as函数来获取参数值
  •  默认值

string name;
int    age;

try {
    po::options_description desc("选项");

    desc.add_options()
        ("help", "print help messages")
        ("name",po::value<string>(), "the name")
        ("age",po::value<int>(&age)->default_value(18), "the age")
        ;

这里通过 &age 来指定默认值。

运行效果:

$ g++ options.cpp  /opt/local/lib/libboost_program_options-mt.a -I /opt/local/include/ -o options_v3

$ ./options_v3
./options_v3
选项:
  --help                print help messages
  --name arg            the name
  --age arg (=18)       the age

$ ./options_v3 --name "Leslie"
The Name: Leslie.
The Age: 18
  • 多选项

#include <iostream>
#include <boost/program_options.hpp>

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

template<class T>
ostream& operator<<(ostream& os, const vector<T>& v)
{
    copy(v.begin(), v.end(), ostream_iterator<T>(os, " "));
    return os;
}

int main(int argc, const char * argv[])
{
    string name;
    int    age;

    try {
        po::options_description desc("选项");

        desc.add_options()
            ("help", "print help messages")
            ("name",po::value<string>(), "the name")
            ("age",po::value<int>(&age)->default_value(18), "the age")
            ("include-path,I", po::value< vector<string> >(), "include path")
            ;

        po::variables_map vm;
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::notify(vm);

        if (vm.count("help")) {
            cout << desc << "\n";
            return 0;
        }

        if (vm.count("name")) {
            cout << "The Name: " << vm["name"].as<string>() << ".\n";
        } else {
            cout << desc << "\n";
            return -1;
        }

        if(vm.count("age")){
            cout << "The Age: " << vm["age"].as<int>()  << "\n";
        } else {
            cout << desc << "\n";
            return -1;
        }

        if(vm.count("I") || vm.count("include-path")) {
            cout << "The include-path: " << vm["include-path"].as< vector<string> >() << "\n";
        } else {
            cout << desc << "\n";
            return -1;
        }
    }

    catch(exception &e) {
        cerr << "error: " << e.what() << "\n";
        return 1;
    }

    catch(...) {
        cerr << "Exception of unknow type!\n";
    }

    return 0;
}

这里因为选项值保存不是int或string类型,因此重载了 << 操作符。

template<class T>
ostream& operator<<(ostream& os, const vector<T>& v)
{
    copy(v.begin(), v.end(), ostream_iterator<T>(os, " "));
    return os;
}
$ g++ options.cpp  /opt/local/lib/libboost_program_options-mt.a -I /opt/local/include/ -o options_v4

$ ./options_v4

选项:
  --help                    print help messages
  --name arg                the name
  --age arg (=18)           the age
  -I [ --include-path ] arg include path

$ ./options_v4 --name Leslie -I ~

The Name: Leslie.
The Age: 18
The include-path: /Users/LeslieZhu

$ ./options_v4 --name Leslie --include-path ~

The Name: Leslie.
The Age: 18
The include-path: /Users/LeslieZhu

$ ./options_v4 --name Leslie --include-path ~ -I ~/Applications/

The Name: Leslie.
The Age: 18
The include-path: /Users/LeslieZhu /Users/LeslieZhu/Applications/

$ ./options_v4 --name Leslie --include-path ~ -I ~/Applications/ -I ~/Library/

The Name: Leslie.
The Age: 18
The include-path: /Users/LeslieZhu /Users/LeslieZhu/Applications/ /Users/LeslieZhu/Library/
  •  位置选项

po::options_description desc("选项");

desc.add_options()
    ("help", "print help messages")
    ("name",po::value<string>(), "the name")
    ("age",po::value<int>(&age)->default_value(18), "the age")
    ("include-path,I", po::value< vector<string> >(), "include path")

    ("input-file", po::value< vector<string> >(), "input file")
    ;

po::positional_options_description p;
p.add("input-file", -1);

po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
po::notify(vm);

 位置选项:

$./options_v5 --name Leslie -I ~ --input-file=options.cpp

The Name: Leslie.
The Age: 18
The include-path: /Users/LeslieZhu
Input files are: options.cpp

$./options_v5 --name Leslie -I ~ --input-file options.cpp

The Name: Leslie.
The Age: 18
The include-path: /Users/LeslieZhu
Input files are: options.cpp


$./options_v5 --name Leslie -I ~ options.cpp

The Name: Leslie.
The Age: 18
The include-path: /Users/LeslieZhu
Input files are: options.cpp
  • 多个输入选项

po::options_description generic("Generic options");
generic.add_options()
    ("version,v", "print version string")
    ("help", "produce help message")
    ("config,c", po::value<string>(&config_file)->default_value("multiple_sources.cfg"),
          "name of a file of a configuration.")
    ;

// Declare a group of options that will be
// allowed both on command line and in
// config file
po::options_description config("Configuration");
config.add_options()
    ("optimization", po::value<int>(&opt)->default_value(10),
          "optimization level")
    ("include-path,I",
         po::value< vector<string> >()->composing(),
         "include path")
    ;

// Hidden options, will be allowed both on command line and
// in config file, but will not be shown to the user.
po::options_description hidden("Hidden options");
hidden.add_options()
    ("input-file", po::value< vector<string> >(), "input file")
    ;


po::options_description cmdline_options;
cmdline_options.add(generic).add(config).add(hidden);

po::options_description config_file_options;
config_file_options.add(config).add(hidden);

po::options_description visible("Allowed options");
visible.add(generic).add(config);

po::positional_options_description p;
p.add("input-file", -1);

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

这段合并选项:

po::options_description cmdline_options;
cmdline_options.add(generic).add(config).add(hidden);

po::options_description config_file_options;
config_file_options.add(config).add(hidden);

po::options_description visible("Allowed options");
visible.add(generic).add(config);

store(po::command_line_parser(ac, av).
      options(cmdline_options).positional(p).run(), vm);

运行效果:

$ ./run --help

Allowed options:

Generic options:
  -v [ --version ]                      print version string
  --help                                produce help message
  -c [ --config ] arg (=multiple_sources.cfg)
                                        name of a file of a configuration.

Configuration:
  --optimization arg (=10)  optimization level
  -I [ --include-path ] arg include path
  •  后记

大致看了看源码,目前来说,很多地方还不是很理解。但这个库功能还是非常强大的。

  • 基本的选项解析
  • 复杂的选项解析
  • 配置文件的解析
  • 环境变量的解析
  • 自定义选项格式
  • 参考

C++: Boost.Program_options

C++ boost::program_options用法

发布了90 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_37160123/article/details/94438531