2009-11-26 6 views
12

J'utilise la bibliothèque boost :: program_options pour traiter les paramètres de la ligne de commande. Je dois accepter un nom de fichier via l'option -r, dans le cas où il est vide (-r donné sans paramètres), j'ai besoin d'utiliser stdin. Dans ce cas, boost n'acceptera pas -r sans params et lèvera une exception. L'option default_value() ne fonctionne pas aussi bien qu'elle rendrait la valeur de retour de la bibliothèque même si l'utilisateur n'a pas donné l'option -r.Comment accepter la valeur vide dans boost :: program_options

Des idées pour contourner?

Répondre

26

S'il vous plaît utiliser la méthode implicit_value, par exemple

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

Cela rend l'option accepte 0 ou 1 jeton, et si aucun jeton sont fournis, il agira comme si « stdin » a été fourni. Bien sûr, vous pouvez choisir n'importe quelle autre valeur implicite - y compris une chaîne vide et '-' comme suggéré par mch.

+0

Merci! Fonctionne parfaitement – cppalex

+0

@Vladimir Prus, voici une autre question sur les options sans valeurs ici http://stackoverflow.com/questions/7174781/boost-program-options-notifier-for-options-with-no-value Je veux être capable d'ajouter des notificateurs pour de telles options ou d'écrire un patch pour l'activer. S'il vous plaît, commentez, merci. – Riga

+0

Malheureusement, cela ne fonctionne pas quand une valeur vide est donnée dans le fichier INI, pour une raison quelconque. –

1

Je ne pense pas que les bibliothèques d'analyse de ligne de commande vous permettent d'avoir des options qui peuvent prendre un argument ou non. Si une option nécessite un argument, vous devez en donner un. Dans ce cas, la pratique standard (dans * NIX de toute façon) consiste à utiliser '-' comme nom de fichier pour indiquer que vous voulez lire depuis l'entrée standard.

+0

Boost :: program_options * permet * cela via zero_tokens(). – Rhubbarb

5

Vous pouvez essayer un truc avec les multitoken et les options zero_tokens: Alors il suffit de compter

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; 

le nombre d'éléments dans le vecteur replay. Vous devez lancer une erreur si plusieurs arguments sont passés à l'option replay.