Cómo aceptar un valor vacío en boost :: program_options
-
05-07-2019 - |
Pregunta
Estoy usando boost :: program_options library para procesar parámetros de línea de comandos. Necesito aceptar un nombre de archivo a través de la opción -r, en caso de que esté vacío (-d dado sin parámetros) necesito usar stdin.
desc.add_options()
("replay,r", boost::program_options::value<std::string>(), "bla bla bla")
En este caso, boost no aceptaría -r sin params y lanzaría una excepción. La opción default_value () no funciona tan bien como haría que la biblioteca devolviera valor incluso si el usuario no ofreciera la opción -r.
¿Alguna idea de cómo trabajar?
Solución
Utilice el método valor implícito
, por ejemplo,
desc.add_options()
("replay,r", po::value<std::string>()->implicit_value("stdin"), "bla bla bla")
Esto hace que la opción acepte 0 o 1 token, y si no se proporcionan tokens, actuará como si se hubiera proporcionado 'stdin'. Por supuesto, puede elegir cualquier otro valor implícito, incluyendo una cadena vacía y '-' como lo sugiere mch.
Otros consejos
Puedes probar un truco con las opciones multitoken
y 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;
Luego solo cuenta el número de elementos en el vector replay
. Querrá lanzar un error si se pasan varios argumentos a la opción repetición .
No creo que ninguna de las bibliotecas de análisis de línea de comandos te permita tener opciones que puedan 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 de una entrada estándar.