boost--program_options 用法詳解

簡介

program options是一系列pair<name,value>組成的選項列表,它允許程序通過命令行或配置文件來讀取這些參數選項.

主要組件

program_options的使用主要通過下面三個組件完成:

組件名 作用
options_description(選項描述器) 描述當前的程序定義了哪些選項
parse_command_line(選項分析器) 解析由命令行輸入的參數
variables_map(選項存儲器) 容器,用於存儲解析後的選項

代碼流程

Created with Raphaël 2.2.0構造option_description對象和variables_map對象add_options()->向option_description對象添加選項parse_command_line()->將命令行輸入的參數解析出來store()->將解析出的選項存儲至variables_map中notify()->通知variables_map去更新所有的外部變量count()->檢測某個選項是否被輸入operator[]->取出選項的值

示例一

下面的代碼是boost::program_options的一個簡單的用法示例.
該示例中指定了兩個選項,分別是–help和–filename.

//linux系統下,編譯選項需加上 -lboost_program_options

#include <iostream>
#include <string>
#include <boost/program_options.hpp>
namespace  bpo = boost::program_options;

int main(int argc, char const *argv[])
{
    //步驟一: 構造選項描述器和選項存儲器
    //選項描述器,其參數爲該描述器的名字
    bpo::options_description opts("all options"); 
    //選項存儲器,繼承自map容器
    bpo::variables_map vm;

    //步驟二: 爲選項描述器增加選項
    //其參數依次爲: key, value的類型,該選項的描述
    opts.add_options()  
    ("filename", bpo::value<std::string>(), "the file name which want to be found")
    ("help", "this is a program to find a specified file");

    //步驟三: 先對命令行輸入的參數做解析,而後將其存入選項存儲器
    //如果輸入了未定義的選項,程序會拋出異常,所以對解析代碼要用try-catch塊包圍
    try{
        //parse_command_line()對輸入的選項做解析
        //store()將解析後的結果存入選項存儲器
        bpo::store(bpo::parse_command_line(argc, argv, opts), vm);
    }
    catch(...){
        std::cout << "輸入的參數中存在未定義的選項!\n";
        return 0;
    }

    //步驟四: 參數解析完畢,處理實際信息
    //count()檢測該選項是否被輸入
    if(vm.count("help") ){//若參數中有help選項
        //options_description對象支持流輸出, 會自動打印所有的選項信息
        std::cout << opts << std::endl;   
    }
    if(vm.count("filename") ){
        //variables_map(選項存儲器)是std::map的派生類,可以像關聯容器一樣使用,
        //通過operator[]來取出其中的元素.但其內部的元素類型value_type是boost::any,
        //用來存儲不確定類型的參數值,必須通過模板成員函數as<type>()做類型轉換後,
        //才能獲取其具體值.
        std::cout << "find " << vm["filename"].as<std::string>() << std::endl;
    }
    if(vm.empty() ){
        std::cout << "no options found \n";
    }
    return 0;
}

在編譯後(假設在linux系統下其編譯後的可執行文件爲a.out)
輸入

./a.out –help

則其輸出爲:

all options:
–filename arg the file name which want to be found
–help this is a program to find a specified file

輸入

./a.out –filename=program_test

則其輸出爲

find program_test

若不指定選項,即輸入

./a.out

則輸出爲

no options found

示例二

下面的這個示例主要用來說明外部變量,參數默認值以及一個選項對應多個值的情況
這段代碼主要有四個選項:

–apple : 蘋果的數量
–orange:橘子的數量
–address:水果的生產地,可指定多個生產地
–help: 打印幫助信息

///////////////////////////////////////////
//計算橘子和蘋果的總數量,可以指定多個生產地    //
//編譯選項加上 -lboost_program_options     //
///////////////////////////////////////////
#include <iostream>  
#include <vector>  
#include <string>  
#include <boost/program_options.hpp>  
namespace bpo = boost::program_options;  

int main(int argc, char const *argv[])  
{  
    //外部變量,用於保存獲取的參數值  
    int apple_num = 0, orange_num = 0;  
    std::vector<std::string> addr;  
    bpo::options_description opt("all options");  

    opt.add_options()  
    //指定該參數的默認值 
    // "apple,a" : 指定選項的全寫形式爲 --apple, 簡寫形式爲 -a
    //value<type>(ptr) : ptr爲該選項對應的外部變量的地址, 當該選項被解析後, 
    //可通過下面的notify()函數將選項的值賦給該外部變量,該變量的值會自動更新
    //defaut_value(num) : num爲該選項的默認值, 若命令行中未輸入該選項, 則該選項的值取爲num
    ("apple,a", bpo::value<int>(&apple_num)->default_value(10), "蘋果的數量")  
    ("orange,o", bpo::value<int>(&orange_num)->default_value(20), "橘子的數量")  
    //該參數的實際類型爲vector,所以命令行中輸入的值可以是多個,
    //multitoken()的作用就是告訴編譯器,該選項可接受多個值  
    ("address", bpo::value<std::vector<std::string> >()->multitoken(), "生產地")  
    ("help", "計算蘋果和橘子的總數量");  

    bpo::variables_map vm;  

    try{  
        bpo::store(parse_command_line(argc, argv, opt), vm);  
    }  
    catch(...){  
        std::cout << "輸入的參數中存在未定義的選項!\n";  
        return 0;  
    }  
    //參數解析完成後,通知variables_map去更新所有的外部變量
    //這句話執行後, 會使得apple_num和orange_num的值自動更新爲選項指定的值   
    bpo::notify(vm);  

    if(vm.count("help") ){  
        std::cout << opt << std::endl;  
        return 0;  
    }  
    if(vm.count("address") ){  
        std::cout << "生產地爲:";  
        //遍歷選項值  
        for(auto& str : vm["address"].as<std::vector<std::string> >() )  
            std::cout << str << " ";  
        std::cout << std::endl;   
    }  
    std::cout << "蘋果的數量:" << apple_num << std::endl;  
    std::cout << "橘子的數量:" << orange_num << std::endl;  
    std::cout << "總數量數量:" << orange_num + apple_num << std::endl;  
    return 0;  
}  

輸入

./a.out –help

輸出

all options:
-a [ –apple ] arg (=10) 蘋果的數量
-o [ –orange ] arg (=20) 橘子的數量
–address arg 生產地
–help 計算蘋果和橘子的總數量

指定蘋果和橘子的數量:

./a.out –apple=8 –orange=20

其輸出爲:

蘋果的數量:8
橘子的數量:20
總數量數量:28

僅指定橘子的數量,不指定蘋果的數量:

./a.out –orange=20

其輸出爲:

蘋果的數量:10
橘子的數量:20
總數量數量:30

可以看到,由於沒有輸入蘋果的數量,所以輸出的蘋果的數量爲我們指定的默認值

指定一個生產地:

./a.out –apple=8 –orange=20 –address=山東

輸出:

生產地爲:山東
蘋果的數量:8
橘子的數量:20
總數量數量:28

指定多個生產地:

./a.out –apple=8 –orange=20 –address=山東 陝西

輸出爲

生產地爲:山東 陝西
蘋果的數量:8
橘子的數量:20
總數量數量:28

簡寫形式的輸入:

./a.out -a 8 -o 20 –address=山東

輸出:

生產地爲:山東
蘋果的數量:8
橘子的數量:20
總數量數量:28

轉載自:https://blog.csdn.net/morning_color/article/details/50241987

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章