這可以做到沒有很多額外的代碼。祕密在於將解析步驟從存儲步驟中分離出來,如在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
AFAIK沒有直接的辦法因爲每個'itemn'都將被視爲一個單獨的選項。你可以做的一件事是定義一個名爲「list」的選項,它的類型爲「vector」,然後當你傳遞參數時,傳遞一個分隔字符串,比如'-list「item1,item2,item3」-list「 item4,item5「-list」item1,tem2「' –
Nim
好吧,如果真的沒有別的辦法,我會考慮這樣做,但我認爲這對用戶來說非常複雜,而且非常不雅觀。 – DerAuenlaender
我試過做過類似的事情,但沒有成功。雖然Boost程序選項對於更簡單的問題是非常好的,但一旦找到用例或對不支持的東西的需求,您基本上必須將其廢棄並編寫自己的命令行參數處理。 –