命令行解析

基本类型支持

boost::program_options可以用于解析命令行参数,常常被用于解析项目运行命令、配置文件、环境变量等到boost::program_options::variables_map,这个map是一个string-boost::program_options::variable_value的键值对集合,variable_value.as<T>()方法能够将其转换到基本数据类型,以及std::vector<T>以及自定义结构体等,见下文。

一个简单实例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <boost/program_options.hpp>

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

int main(int argc, char* argv[]){
//创建解析对象
try{
program_options::options_description pod("test options");
pod.add_options() //添加解析选项,在命令行中只需要-h或者--help
("help,h", "Show Help Info")
("showNum,s", program_options::value<int>()->default_value(10), "Set Int Num")
("outputName,o", program_options::value<std::string>(), "Set File Name");

//创建解析结构
program_options::variables_map vm;
//命令行按选项解析
program_options::store(program_options::parse_command_line(argc, argv, pod), vm);
//更新vm捕获的选项
program_options::notify(vm);

if(vm.count("help")) //存在-h参数
cout << "All Options: " <<pod << endl; //支持直接打印选项

if(vm.count("showNum")){
int num = vm.at("showNum").as<int>();
cout << "Num: " << num << endl;
}

if(vm.count("outputName")){
string name = vm.at("outputName").as<std::string>();
cout << "Name: " << name << endl;
}

//打印program_options::variables_map
for(const auto& pos : vm){
if(pos.first != "showNum")
cout << pos.first << "-" << pos.second.as<std::string>() << endl;
else
cout << pos.first << "-" << pos.second.as<int>() << endl;
}
}
catch(program_options::error &e){
cerr << "Error: " << e.what() << endl;
}
return 0;
}

测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
.\test3.exe -s 10 -o "1233333333" -h

#输出:
All Options: test options:
-h [ --help ] Show Help Info
-s [ --showNum ] arg (=10) Set Int Num
-o [ --outputName ] arg Set File Name

Num: 10
Name: 1233333333
help- #无设置为空
outputName-1233333333 #无默认值时该项缺省
showNum-10

STL(vector)与自定义结构支持

除了string、int、double/float、long等基本数据类型支持,boost::program_options还直接支持解析到vector<T>类型:

1
2
3
4
5
6
7
8
9
10
11
pod.add_options() //添加解析选项,在命令行中只需要-h或者--help
("help,h", "Show Help Info")
("outputName,o", program_options::value<std::string>(), "Set File Name");

//....解析如上
if(vm.count("vp")){
vector<double> vp = vm.at("vp").as<vector<double>>();
for(const auto& pos : vp){
cout << pos << " ";
}
}

测试:

1
2
3
.\test3.exe -v 1.2 -v 2.4 -v 3.6
#输出:
1.2 2.4 3.6

对于自定义类型,只要能通过std:istream序列化结构体,boost::program_options就能够支持结构体转换:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <boost/program_options.hpp>
#include <opencv2/opencv.hpp>
#include <sstream>

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

struct Test{
cv::Point point;
int num;

void printInfo(){
cout << "Info: " << point.x << point.y << num << endl;
}
};

std::istream& operator>>(std::istream& input, Test& test){
char ch; //吞掉命令行的逗号间隔
input >> test.point.x >> ch >> test.point.y >> ch >> test.num;
return input;
}

int main(int argc, char* argv[]){
try{
program_options::options_description pod("test options");
pod.add_options()
("help,h", "Show Help Info")
("SelfStruct,t", program_options::value<Test>());

program_options::variables_map vm;
program_options::store(program_options::parse_command_line(argc, argv, pod), vm);
program_options::notify(vm);

if(vm.count("help"))
cout << "All Options: " <<pod << endl;

if(vm.count("SelfStruct")){
Test test = vm.at("SelfStruct").as<Test>();
test.printInfo();
}
}
catch(program_options::error &e){
cerr << "Error: " << e.what() << endl;
}

return 0;
}

测试:

1
2
3
.\test3.exe -t 1,2,3
#输出:
Info: 123