由于系统库getopt和getopt_long用起来不够直观,仔细看了下boost发现Boost.Program_options 可以满足我的需求,它和getopt系列函数一样,可以抓起命令行参数,这里写下我对Boost.Program_options的理解。
一、getopt的不足
使用过了getopt函数后,我感觉它不足的地方(可能是我没研究明白的问题),我觉得getopt系列函数的不足有下面几点:
1、使用switch-case语句,导致程序看起来不是太美观,不怎么好看
2、没法使用一个参数接受N个值,如-a 1 2 3 4..n -b..这样
3、程序里变量的控制,只是一些自己定义的字符(如v,h等等),只有程序设计的人才知道这些字符代表的什么意思,做不到一目了然,与现代程序设计不符合
当然getopt也有自己优势,这里就不再罗嗦,直接开始boost命令行参数。
二、使用前准备
当然我们在使用boost库时,需要安装boost库,这里也不再罗嗦,自己上网搜索,很简单。在使用的时候,我们要首先引入头文件:#include <boost/program_options.hpp>,同时不要忘记了要使用该boost库的命名空间:boost::program_options
三、实战
由于boost库的写法比较怪异,跟我们平常的写法有所区别,最好先把程序运行下,然后再看程序,能够很快理解程序的意思,下面的例子由易到难。
例子1
#include<iostream> #include <boost/program_options.hpp> using namespace std; using namespace boost::program_options; int main(int argc, char **argv) { options_description desc("Allowed options"); desc.add_options() ("help", "produce help message") ("compression", value<int>(), "set compression level") ; variables_map vm; store(parse_command_line(argc, argv, desc), vm); 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"; } }
编译:g++ -L/usr/local/lib -lboost_program_options
结果:./a.out --help
Allow options:
--help produce help message
--compresion arg set compression level
./a.out --compression 10
Compression level was set to 10
上面的例子我们只是演示的只有int类型,还可以有其他的类型,同时上面的例子,也是无法做到一个参数后跟N个值,下面就说怎么解决这个问题
例子2
#include<iostream> #include <boost/program_options.hpp> using namespace std; using namespace boost::program_options; int main(int argc, char **argv) { int opt; options_description desc("Allowed options"); desc.add_options() ("help", "produce help message") ("compression", value<int>(), "set compression level") ("optimizaiton", value<int>(&opt)->default_value(10), "optimization level") ("input-file,i", value<vector<string>>(), "input file")//这里注意input-file和i之间不能有空格 ("include-path", value<vector<int>>(), "include path") ; //note here positional_options_description p; p.add("include-path“, -1) //这里只会有一个生效,就是后面的那个,他会把命令行中哪些没有参数值默认为 //你这里设置的值 //p.add("include-path", -1) variables_map vm; store(command_line_parser(argc, argv).options(desc).positional(p).run(), vm); 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"; } if (vm.count("include-path")) { for (auto& v: vm["include-path"].as<vector<int>>()) { cout << "include-path: " << v << endl; } } if (vm.count("input-file")) { for (auto &v : vm["input-file"].as<vector<string>>()) { cout << "input-file: " << v << endl; } } }
测试结果:
./a.out --compression 10 -i a.cpp --include-path 10 20 40
Compression level was set 10.
input-file: a.cpp
include-path: 10
include-path: 20
include-path: 40
下面介绍多个options_description之间的配合使用,这样让你的程序更加专业化
#include<iostream> #include <boost/program_options.hpp> #include <string> #include <vector> using namespace std; using namespace boost::program_options; int main(int argc, char **argv) { options_description generic("Generic options"); generic.add_options() ("version,v", "print version string") ("help,h", "produce help message") ; int opt = 0; options_description config("Configuration"); config.add_options() ("optimization", value<int>(&opt)->default_value(10), "optimization level") ("include-path,I", value<string>(),"include path") ("compression", value<int>(), "compression") ; options_description hidden("Hidden options"); hidden.add_options() ("input-file", value<vector<string>>(), "input file") ; options_description cmdline_options("Allow options"); cmdline_options.add(generic).add(config).add(hidden); positional_options_description p; p.add("input-file", -1); variables_map vm; store(parse_command_line(argc, argv). options(cmdline_options).positional(p).run(), vm); 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"; } if (vm.count("input-file")) { for (auto &v : vm["input-file"].as<vector<string>>()) { cout << "input-file: " << v << endl; } } }
结果:
Allow options:
Generic options:
-v [--version] print version string
-h [--help] produce help message
Configuration:
--optimization arg(=10) optimization level
-I [ --include-path ] arg include path
--compression arg compression
Hidden options:
--input-file args input file
下面尽可能解释一下,程序中的难点,解释不对的地方欢迎指正~
1、
欢迎转载,但是请指明出处以及作者,谢谢~