2013-04-01 3 views
6

Прежде чем вы скажете OVERKILL, мне все равно.Обработка «-» с boost.program_options

Как я могу сделать Boost.program_options обрабатывать необходимый параметр cat-?

У меня есть

// visible 
po::options_description options("Options"); 
options.add_options()("-u", po::value<bool>(), "Write bytes from the input file to the standard output without delay as each is read."); 

po::positional_options_description file_options; 
file_options.add("file", -1); 

po::variables_map vm; 
po::store(po::command_line_parser(argc, argv).options(options).positional(file_options).run(), vm); 
po::notify(vm); 

bool immediate = false; 
if(vm.count("-u")) 
    immediate = true; 
if(vm.count("file")) 
    support::print(vm["file"].as<vector<string>>()); 

, который вызывает исключение при запуске cat - - -:

непризнанного варианта '-'

Я хочу это видеть - как позиционный аргумент, и мне нужно это в правильном порядке в полном списке файлов. Как я мог это достичь?

UPDATE

У меня есть половина исправления. Мне нужно было

po::options_description options("Options"); 
options.add_options()("-u", po::value<bool>(), "Write bytes from the input file to the standard output without delay as each is read.") 
        ("file", po::value< vector<string> >(), "input file"); 

po::positional_options_description file_options; 
file_options.add("file", -1); 

Проблема, я, кажется, только получить 2 из трех -, когда я вывожу аргументы:

if(vm.count("file")) 
    support::print(vm["file"].as<vector<string>>()); 

где поддержка :: печать красиво обрабатывает вектор и прочее.

+0

Boost.PO имеет свою собственную (вроде ограниченного) синтаксиса опций. Вероятно, вы можете использовать Boost.PO для синтаксиса, который вы хотите. – Abyx

+0

@Oli: сделано. Благодарю. – rubenvb

ответ

4

Вам нужно определить именованный вариант программы, который является позиционной, в вашем случае это file

#include <boost/foreach.hpp> 
#include <boost/program_options.hpp> 

#include <iostream> 
#include <string> 
#include <vector> 

namespace po = boost::program_options; 

int 
main(int argc, char* argv[]) 
{ 
    std::vector<std::string> input; 
    po::options_description options("Options"); 
    options.add_options() 
     ("-u", po::value<bool>(), "Write bytes from the input file to the standard output without delay as each is read.") 
     ("file", po::value(&input), "input") 
     ; 

    po::positional_options_description file_options; 
    file_options.add("file", -1); 

    po::variables_map vm; 
    po::store(po::command_line_parser(argc, argv).options(options).positional(file_options).run(), vm); 
    po::notify(vm); 

    bool immediate = false; 
    if(vm.count("-u")) 
     immediate = true; 
    BOOST_FOREACH(const auto& i, input) { 
     std::cout << "file: " << i << std::endl; 
    } 
} 

Вот coliru demo и выход, если вы не хотите щелкать через

$ g++ -std=c++11 -O2 -pthread main.cpp -lboost_program_options && ./a.out - - - 
file: - 
file: - 
file: - 

Если вы видите только 2 из 3 позиционных аргументов, это, скорее всего, потому, что argv[0] по условному названию программы, и поэтому не рассматривается для разбора аргументов. Это можно увидеть в исходном коде для basic_command_line_parser шаблона

37  template<class charT> 
38  basic_command_line_parser<charT>:: 
39  basic_command_line_parser(int argc, const charT* const argv[]) 
40  : detail::cmdline(
41   // Explicit template arguments are required by gcc 3.3.1 
42   // (at least mingw version), and do no harm on other compilers. 
43   to_internal(detail::make_vector<charT, const charT* const*>(argv+1, argv+argc+!argc))) 
44  {} 
+0

Спасибо, но я уже понял, что часть. Кажется, что мое вмешательство в argv - это не то, что ожидалось boost.program_options, и он игнорировал первый argv, хотя я удалил argv [0]. – rubenvb

+0

@rubenvb, вероятно, вы должны пометить вопрос как [тег: windows] или некоторые такие, то, как выглядит ваш 'argv'? –

Смежные вопросы