2

我有一个使用 boost v1.45.0 程序选项的 Visual Studio 2008 C++ 应用程序。

我希望能够解析一个看起来像这样的命令行选项:foo.exe -x 1,2, 4-7这样它会产生一个std::vector< int >值为 [1, 2, 4, 5, 6, 7] 的值。所以,我写了一个自定义验证器:

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.

我需要做什么才能使这项工作如愿以偿?

谢谢,保罗

4

3 回答 3

1

typedef std::vector<int>as aboost::program_options::value_semantic不能按您希望的方式工作,因为 a对程序选项库vector具有特殊含义:

该库为向量提供了特殊支持——可以多次指定选项,并且所有指定的值都将收集在一个向量中。

这意味着这样的描述

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

std::vector<int>在给定以下命令行的情况下合并为一个

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

结果将是一个std::vector有四个元素的。你需要定义一个特定的类型来使用自定义验证器,struct IDList才是正确的做法

于 2011-02-26T01:41:05.213 回答
0

您可以尝试编写自己的函数来解析命令行选项:

看这里

您编写自己的解析器函数,例如 reg_foo,并按如下方式使用它:

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

另请参阅 example/custom_syntax.cpp 中与 boost 一起分发的示例代码

于 2011-02-25T17:43:20.080 回答
0

问题是 的定义IDList。如果我更改定义以匹配示例中magic_number使用的类型,它会起作用。regex.cpp

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

我还没有调查为什么 atypedef是框架的问题,但这有效。

-保罗H

于 2011-02-25T19:51:55.713 回答