2009-11-26 14 views
12

sto usando spinta biblioteca :: program_options per elaborare params riga di comando. Devo accettare un nome file tramite l'opzione -r, nel caso in cui sia vuota (-r dato senza params) Ho bisogno di usare stdin.come accettare valore vuoto in boost :: program_options

desc.add_options() 
("replay,r", boost::program_options::value<std::string>(), "bla bla bla") 

In questo caso, boost non accetta -r senza parametri e genera un'eccezione. L'opzione default_value() non funziona così come renderebbe il valore di ritorno della libreria anche se l'utente non ha fornito l'opzione -r.

Tutte le idee come risolvere?

risposta

26

Si prega di utilizzare il metodo implicit_value, per esempio

desc.add_options() 
("replay,r", po::value<std::string>()->implicit_value("stdin"), "bla bla bla") 

Questo rende l'opzione accetta 0 o 1 gettone, e se non sono previste gettoni, agirà come se è stato fornito 'stdin'. Ovviamente, puoi scegliere qualsiasi altro valore implicito, inclusa la stringa vuota e "-" come suggerito da mch.

+0

Grazie! Funziona perfettamente – cppalex

+0

@Vladimir Prus, qui è un'altra questione della scelta senza valori qui http://stackoverflow.com/questions/7174781/boost-program-options-notifier-for-options-with-no-value voglio essere in grado di aggiungere notificatori per tali opzioni o scrivere una patch per abilitarlo. Per favore, commenta, grazie. – Riga

+0

Sfortunatamente, questo non funziona quando un valore vuoto viene dato nel file INI, per qualche motivo. –

1

non credo che le librerie della riga di comando di analisi consentono di avere opzioni che possono prendere un argomento o meno. Se un'opzione richiede un argomento, devi darlo. In questo caso, la pratica standard (in * NIX comunque) è usare '-' come nome file per indicare che si desidera leggere dallo standard input.

+0

Boost :: program_options * does * consente questo tramite zero_tokens(). – Rhubbarb

5

Si potrebbe provare un trucco con le opzioni multitoken e zero_tokens:

using namespace std; 
namespace po = boost::program_options; 

vector<string> replay; 

po::options_description desc("Allowed options"); 
desc.add_options() 
    ("replay,r", po::value< vector<string> >(&replay)->multitoken()->zero_tokens(), "bla bla bla"); 

po::variables_map vm;   
po::store(po::parse_command_line(argc, argv, desc), vm); 
po::notify(vm);  

if (vm.count("replay")) 
{ 
    size_t s = vm["replay"].as< vector<string> >().size(); 
    if (s == 0) 
    cout << "replay without args" << endl; 
    else if (s == 1) 
    cout << "replay with one arg" << endl; 
    else 
    cout << "replay with multiple args" << endl; 
} 
else 
    cout << "replay not specified" << endl; 

Poi basta contare il numero di elementi nella replay vettoriale. Dovresti generare un errore se vengono passati più argomenti all'opzione replay.

Problemi correlati