2011-02-25 65 views
2

我有一個使用boost v1.45.0程序選項的Visual Studio 2008 C++應用程序。使用boost程序選項無效的選項值異常

我想能夠解析一個命令行選項,看起來像這樣:foo.exe -x 1,2, 4-7,使它產生一個值爲[1,2,4,5,6,7]的std::vector<int>。所以,我寫了一個自定義驗證程序:

typedef std::vector<int> IDList; 

void validate(boost::any& v, const std::vector<std::string>& tokens, IDList*, int) 
{ 
    // Never gets here 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    IDList test_case_ids; 

    po::options_description desc("Foo options"); 
    desc.add_options() 
     ("id,x", po::value<IDList>(), "Specify a single ID or a range of IDs as shown in the following command line: foo.exe -x10,12, 15-20") 
    ; 

    po::variables_map vm; 

    try 
    { 
     po::store(po::parse_command_line(argc, argv, desc), vm); 
     po::notify(vm); 
    } 
    catch(const std::exception& e) 
    { 
     std::cerr << e.what() << std::endl; 
     std::cout << desc << std::endl; 
     return 1; 
    } 

    return 0; 
} 

但是,我從來沒有得到我的自定義驗證代碼。我總是在parse_command_line中發現異常,並提示信息:in option 'id': invalid option value

我需要做什麼才能使這項工作按需要進行?

感謝, PaulH

+0

當您運行時,您提供的命令行是什麼? – Dennis 2011-02-25 17:42:14

+0

順便說一句 - 你在編譯使用UNICODE ...在這種情況下,你需要使用庫操作的wstring版本。 – Dennis 2011-02-25 17:51:02

+0

@丹尼斯 - 命令行是'foo.exe -x 1,2,4-7'。是的,我正在編譯UNICODE標誌。更改爲'std :: wstring'不會改變結果。我得到同樣的例外。 – PaulH 2011-02-25 18:06:19

回答

1

的類型定義std::vector<int>作爲boost::program_options::value_semantic不工作,你的願望,因爲一個vectorspecial meaning的程序選項庫的方式:

該庫提供了載體的特殊支持 - - 將有可能 多次指定選項,並且 將在一個向量中收集所有指定值 。

這意味着像這樣

typedef std::vector<int> IDList; 
po::options_description desc("Foo options"); 
desc.add_options() 
    ("id,x", po::value<IDList>(), "list of IDs") 
; 

一個說明合併到給定下面的命令行

a.out --id 1 --id 2 --id 3 --id 4 

的結果將是一個std::vector具有四個元件的單個std::vector<int>。您需要定義特定類型以使用自定義驗證器,struct IDListcorrect approach

+0

這很有道理。謝謝! – PaulH 2011-02-28 03:10:27

+0

你是說在這種情況下類型(def)IDList是'魔術'?也就是說它必須被命名爲IDList而不是別的? – 2012-03-02 16:31:28

0

你可以嘗試編寫自己的函數來解析命令行選項:

See here

你寫你自己的解析器功能,例如reg_foo,並如下使用它:

variables_map vm; 
store(command_line_parser(argc, argv).options(desc).extra_parser(reg_foo) 
      .run(), vm); 

參見與升壓分佈的例子的代碼,在例如/ custom_syntax.cpp

+0

我想我可以做到這一點,但我只需要'-x'選項的自定義分析器。我認爲這是自定義驗證器的用途? – PaulH 2011-02-25 18:11:26

0

的問題是IDList定義。如果我將該定義更改爲與regex.cpp示例中使用的magic_number類型相匹配,則它將起作用。

struct IDList 
{ 
public: 
    std::vector<int> ids_; 
    IDList(std::vector<int> ids) : ids_(ids) {} 
}; 

我沒有調查爲什麼typedef是框架的一個問題,但這個工程。

-PaulH

+0

如果我不能接受2天,讓我發佈答案,這有什麼意義? – PaulH 2011-02-25 19:53:41

+0

爲了鼓勵其他答案,您不會通過回答自己的問題獲得回饋。 – 2011-02-25 21:07:19

+0

@Sam - 我不清楚。我的意思是,「如果我不能將它標記爲2天的答案,爲什麼讓我發佈答案?」。 – PaulH 2011-02-25 21:27:03