Boost命令行解釋器的簡單使用:Boost.Program_options

簡介

如果使用比較多的命令行程式的話,對於命令行參數的輸入肯定不會陌生,大部分的程式都是通過類似下面的形式進行輸入的,比如熟悉的ls

ls --all -l --color=auto

這裡面包含了三種不同的命令行輸入--all-l--color=auto。如果使用一般的解決方法的話,是使用getopt.h文件中的getopt函數。其具體的教程可以看《Linux下getopt()函數的簡單使用》,其使用方法比較麻煩。而且只支援一個字元的選項,如果要像--color=auto一樣支援長選項,必須再使用getopt_long函數,而且由於其是對C進行支援的,所以在C++中使用起來也比較麻煩。

而Boost提供的Program_options庫可以很好的解決這一問題。Program_options提供了一個成熟的C++庫來解析命令行參數,幾行簡單清晰的程式碼就可以描繪出一個完整的命令行解析器。

而其的使用方法也是非常的簡單,大致可以分為三個部分,構建解析器對象,解析命令行參數,使用結果。

使用的時候需要鏈接boost_program_options庫

沒有參數的選項

一個非常簡單的例子,只定義了一個選項help,運行時會直接先列印獲取到的var_mapname,然後檢查是否存在help選項,如果存在則列印命令行幫助,如果不存在,就直接推出。

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

int main(int argc, char *argv[]) {
    boost::program_options::options_description desc("測試程式");

    desc.add_options()("help,h", "列印幫助文檔");

    boost::program_options::variables_map var_map;
    boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), var_map);
    boost::program_options::notify(var_map);

    for (auto iter : var_map) {
        std::cout << iter.first << std::endl;
    }


    if (var_map.count("help") > 0) std::cout << desc << std::endl;
    return 0;
}

編譯以後運行./main_simple -h或者./main_simple --help可以得到:

help
測試程式:
  -h [ --help ]         列印幫助文檔

首先是定義了一個boost::program_options::options_description對象,它可以選項列表的描述。它的構造函數可以傳入一個字元串,作為列印時候的抬頭。

然後是向選項列表裡面添加選項,最簡單的方法就是使用desc對象裡面的add_options方法,它可以返回一個函數對象,藉此向選項列表描述添加選項。

目前在這裡的選項列表只有簡單的兩個參數,第一個是表明選項的name,你可以通過用分號將長選項和縮寫分割開來,而最終的結果還是以長選項作為name的;第二個是對選項的描述。

然後定義了一個boost::program_options::variables_map對象,它是一個map,key元素為選項的name,value元素為Boost::any對象。

然後開始對命令行輸入進行解析,首先使用boost::program_options::parse_command_line進行解析,然後使用boost::program_options::store將結果保存在var_map變數裡面。

接下來,就是對map的操作了。而如果想輸出說明的話,也可以很直接的直接對desc進行cout

帶參數的選項

上面我們介紹了不帶參數的簡單使用,但是在很多的時候,我們需要通過命令行輸入一些參數。就如同最上面例子中的--color=auto一樣。Boost提供了非常簡單的方法來實現這一操作。

#include <vector>
#include <string>
#include <iostream>

#include <boost/program_options.hpp>

int main(int argc, char *argv[]) {
    boost::program_options::options_description desc("測試程式");

    desc.add_options()("help,h", "列印幫助文檔");
    desc.add_options()("input,i", boost::program_options::value<std::string>()->default_value("Test")->value_name("string"), "輸入");

    boost::program_options::variables_map var_map;
    boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), var_map);
    boost::program_options::notify(var_map);


    if (var_map.count("help") > 0) std::cout << desc << std::endl;
    if (var_map.count("input") > 0) std::cout << var_map["input"].as<std::string>() << std::endl;
    return 0;
}

在這個程式中,增加了一行

desc.add_options()("input,i", boost::program_options::value<std::string>()->default_value("Test")->value_name("string"), "輸入");

和之前的help選項類似,在這裡我們增加了一個input選項,在這個添加過程中,我們向函數對象添加了3個參數,第一個和第三個參數和之前表述的一樣。而第二個參數可以看作是對輸入的描述。

首先我們通過boost::program_options::value構造了一個對象,在構造的過程中,需要向模板傳入一個類型參數,表表明輸入值的類型。然後其會構造出一個boost::program_options::type_value類型,可以通過一些方法對其進行設置。

在這一示例中,用戶可以在input後面輸入一個字元串,同時如果沒有輸入的話,會主動出現一個默認值Test,這個默認值會在沒有輸入的時候作為input項的默認值。

然後可以通過對var_map進行簡單的操作,來獲取輸入的值。

其他雜項

很明顯,Boost.Program_options的操作肯定還不止這一些,但是以上的簡單操作,基本上可以覆蓋大部分的使用場景了。然後還有一些使用的小細節。

報錯

如果輸入的選項中存在描述中沒有的選項的話,就會在解析的時候產生一個異常,可以通過捕捉這一個異常,給程式一個更加合理的表現。

隱藏項

如果想給程式增加一個「後門」,只有你知道的選項,應該如何操作呢?

其實很簡單,建立兩個options_description就好了,一個用來顯示,一個用來解析。這樣就不會在顯示的時候,顯示需要隱藏的項了。

轉載註明源地址://www.cnblogs.com/ink19/p/Boost_Program_options.html

Tags: