2009-11-26 6 views
12

Estoy usando la biblioteca boost :: program_options para procesar parámetros de línea de comandos. Necesito aceptar un nombre de archivo mediante la opción -r, en caso de que esté vacío (-r dado sin params) Necesito usar stdin.Cómo aceptar el valor vacío en boost :: program_options

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

En este caso boost no aceptará -r sin params y arrojará una excepción. la opción default_value() no funciona tan bien como haría que la biblioteca devuelva valor incluso si el usuario no dio la opción -r.

¿Alguna idea de cómo solucionarlo?

Respuesta

26

Por favor, utilice el método implicit_value, por ejemplo

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

Esto hace que la opción de aceptar 0 o 1 manera, y si no se proporcionan fichas, actuará como si se proporcionó 'stdin'. Por supuesto, puede elegir cualquier otro valor implícito, incluida la cadena vacía y '-' como lo sugiere mch.

+0

¡Gracias! Funciona perfectamente – cppalex

+0

@Vladimir Prus, aquí hay otra pregunta sobre las opciones sin valores aquí http://stackoverflow.com/questions/7174781/boost-program-options-notifier-for-options-with-no-value Quiero ser capaz de agregar notificadores para tales opciones o escribir un parche para habilitarlo. Por favor, comenten, gracias. – Riga

+0

Desafortunadamente, esto no funciona cuando se da un valor vacío en el archivo INI, por alguna razón. –

1

No creo que ninguna biblioteca de análisis de línea de comandos le permita tener opciones que pueden tomar un argumento o no. Si una opción requiere un argumento, debe dar uno. En este caso, la práctica estándar (en * NIX de todos modos) es usar '-' como nombre de archivo para indicar que desea leer desde la entrada estándar.

+0

Boost :: program_options * does * permite esto a través de zero_tokens(). – Rhubbarb

5

Usted podría intentar un truco con los multitoken y zero_tokens opciones:

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; 

A continuación, sólo contar el número de elementos en el vector replay. Tendrá que lanzar un error si se pasan varios argumentos a la opción de reproducción .

Cuestiones relacionadas