2013-04-01 17 views
6

Prima di dire OVERKILL, non mi interessa.Gestione '-' con boost.program_options

Come posso rendere Boost.program_options gestire l'opzione cat richiesta -?

ho

// 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>>()); 

che genera un'eccezione quando corro cat - - -:

opzione non riconosciuta '-'

voglio che vedere - come argomento posizionale, e ne ho bisogno nell'ordine corretto nella lista completa dei file. Come potrei ottenere questo?

UPDATE

Ho un mezzo correzione. Avevo bisogno

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); 

Il problema è che, mi sembra di ottenere solo 2 dei tre - quando l'uscita ho gli argomenti:

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

in cui il sostegno :: stampa ben gestisce il vettore e roba.

+0

Boost.PO ha il suo (sorta di limitata) la sintassi di opzioni. Probabilmente puoi utilizzare Boost.PO per la sintassi che desideri. – Abyx

+0

@Oli: completato. Grazie. – rubenvb

risposta

4

è necessario definire l'opzione di programma denominato che è posizionale, nel tuo caso è 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; 
    } 
} 

Ecco un coliru demo e l'uscita se non si desidera scegliere attraverso

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

Se si vedono solo 2 di 3 argomenti posizionali, è probabile perché argv[0] è per convenzione il nome del programma ed è pertanto non considerato per l'analisi degli argomenti. Questo può essere visto nel codice sorgente per il modello 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

Grazie, ma ho già capito quella parte. Sembra che la mia intromissione con argv non sia ciò che ci si aspettava da boost.program_options e ha ignorato il primo argv, anche se ho rimosso argv [0]. – rubenvb

+0

@rubenvb dovresti probabilmente taggare la domanda come [tag: windows] o qualcosa del genere quindi, come appare il tuo 'argv'? –