2009-11-26 2 views
12

Я использую boost :: program_options библиотеку для обработки параметров командной строки. Мне нужно принять имя файла через -r, если оно пусто (-r задано без параметров) Мне нужно использовать stdin.Как принять пустое значение в boost :: program_options

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

В этом случае boost не принимает -r без параметров и генерирует исключение. default_value() не работает так же, как и для возвращаемого значения библиотеки, даже если пользователь не предоставил параметр -r.

Любые идеи, как работать?

ответ

26

Пожалуйста, используйте implicit_value метод, например

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

Это делает возможность принимать либо 0, либо 1 фишку, и если не указаны лексемы, он будет действовать, как если бы была предоставлена ​​"STDIN. Конечно, вы можете выбрать любое другое неявное значение - включая пустую строку и «-», как было предложено mch.

+0

Спасибо! Прекрасно работает – cppalex

+0

@Vladimir Prus, вот еще вопрос о вариантах без значений здесь http://stackoverflow.com/questions/7174781/boost-program-options-notifier-for-options-with-no-value Я хочу иметь возможность добавлять уведомления для таких параметров или писать патч, чтобы включить его. Прошу прокомментировать, спасибо. – Riga

+0

К сожалению, это не работает, когда пустое значение указывается в файле INI по какой-либо причине. –

1

Я не думаю, что какие-либо библиотеки синтаксического анализа командной строки позволят вам иметь параметры, которые могут принимать аргумент или нет. Если для параметра требуется аргумент, вы должны указать его. В этом случае стандартная практика (в * NIX в любом случае) заключается в использовании «-» в качестве имени файла для обозначения того, что вы хотите читать со стандартного ввода.

+0

Boost :: program_options * делает * разрешает это через zero_tokens(). – Rhubbarb

5

Вы можете попробовать трюк с multitoken и 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; 

Тогда просто подсчитать количество элементов в векторе replay. Вы захотите выбросить ошибку, если несколько аргументов переданы в опцию replay.

Смежные вопросы