2016-02-01 62 views
2

我目前正在與boost::program_options一起工作。我的程序應該將任意長度的「列表」作爲參數(其中包括......)。例如,用戶應該能夠調用C++:Boost program_options:多個參數列表

./myprogram -list item1 item2 item3 -list item1 item2 -list item1 item2 

很顯然,我不希望得到一個列表/矢量與所有項目一個接一個結果,但(在這種情況下)三個列表/矢量(或者,例如,包含元素的矢量的一個矢量),每個列表有兩個或三個項目(每個項目應該是一個字符串,但我想這不重要)。 正如我之前所說的,列表的數量(以及每個列表的項目數量!)應該是任意的。 我該怎麼做boost::program_options

+2

AFAIK沒有直接的辦法因爲每個'itemn'都將被視爲一個單獨的選項。你可以做的一件事是定義一個名爲「list」的選項,它的類型爲「vector 」,然後當你傳遞參數時,傳遞一個分隔字符串,比如'-list「item1,item2,item3」-list「 item4,item5「-list」item1,tem2「' – Nim

+0

好吧,如果真的沒有別的辦法,我會考慮這樣做,但我認爲這對用戶來說非常複雜,而且非常不雅觀。 – DerAuenlaender

+1

我試過做過類似的事情,但沒有成功。雖然Boost程序選項對於更簡單的問題是非常好的,但一旦找到用例或對不支持的東西的需求,您基本上必須將其廢棄並編寫自己的命令行參數處理。 –

回答

3

這可以做到沒有很多額外的代碼。祕密在於將解析步驟從存儲步驟中分離出來,如在this answer中所做的那樣。

解析器將返回一個鍵/值結構的容器,因爲這些選項是從用戶提供的。如果一個選項被多次提交,那麼容器將爲每個選項提交一個單獨的條目。無論我們想要掃描一個特定的選項並組織它的值,這是非常簡單的。

下面是打印出的每個輸入多令牌選項在單獨一行的例子:

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

#include <boost/program_options.hpp> 

namespace po = boost::program_options; 

int main(int argc, char *argv[]) { 
    // Define a multi-token option. 
    po::options_description desc("Allowed options"); 
    desc.add_options() 
     ("list", po::value<std::vector<std::string>>()->multitoken(), "multiple values"); 

    // Just parse the options without storing them in a map. 
    po::parsed_options parsed_options = po::command_line_parser(argc, argv) 
     .options(desc) 
     .run(); 

    // Build list of multi-valued option instances. We iterate through 
    // each command-line option, whether it is repeated or not. We 
    // accumulate the values for our multi-valued option in a 
    // container. 
    std::vector<std::vector<std::string>> lists; 
    for (const po::option& o : parsed_options.options) { 
     if (o.string_key == "list") 
     lists.push_back(o.value); 
    } 

    // If we had other normal options, we would store them in a map 
    // here. In this demo program it isn't really necessary because 
    // we are only interested in our special multi-valued option. 
    po::variables_map vm; 
    po::store(parsed_options, vm); 

    // Print out the multi-valued option, each separate instance on its 
    // own line. 
    for (size_t i = 0; i < lists.size(); ++i) { 
     for (size_t j = 0; j < lists[i].size(); ++j) 
     std::cout << lists[i][j] << ' '; 
     std::cout << '\n'; 
    } 

    return 0; 
} 

這裏是一個示例調用(live at coliru):

$ ./po --list 1 2 3 --list foo bar --list how now brown cow 
1 2 3 
foo bar 
how now brown cow