2011-02-25 59 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