недопустимое исключение значения параметра при использовании опций программы - PullRequest
2 голосов
/ 25 февраля 2011

У меня есть приложение Visual Studio 2008 C ++, использующее параметры программы boost v1.45.0.

Я хотел бы иметь возможность проанализировать параметр командной строки, который выглядит следующим образом: 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.

Что мне нужно сделать, чтобы сделать эту работу по желанию?

Спасибо, PaulH

Ответы [ 3 ]

1 голос
/ 26 февраля 2011

typedef std::vector<int> как boost::program_options::value_semantic не работает так, как вы хотите, потому что 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 - это правильный подход .

0 голосов
/ 25 февраля 2011

Проблема в определении IDList. Если я изменю определение, чтобы оно соответствовало типу magic_number, используемому в образце regex.cpp, это сработает.

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

Я не исследовал, почему typedef является проблемой для фреймворка, но это работает.

-PaulH

0 голосов
/ 25 февраля 2011

Вы можете попробовать написать свою собственную функцию для разбора параметров командной строки:

Смотрите здесь

Вы пишете свою собственную функцию синтаксического анализатора, например, reg_foo, и используете ееследующим образом:

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

См. также пример кода, распространяемого с boost, в example / custom_syntax.cpp

...