How to have an optional option value in boost program options?
Asked Answered
B

1

24

I am using the Boost program option and I want to offer an option which has three ways:

  1. If not define
  2. If defined but no value
  3. If defined with a value

For example, I have a program that works on a file such as a.jpg, and I want to offer the user to be able to use it in the following scenarios:

myapp.exe a.jpg  : process jpeg 
myapp.exe a.jpg -e : process jpeg and generate report at the same directory as a.jpg
myapp.exe a.jpg -e c:\tmp\ : process jpeg and generate report at c:\tmp\

How can I do this with Boost program options?

Bertabertasi answered 10/8, 2015 at 13:44 Comment(0)
S
30

You can achieve this effect by giving the value both a default_value and an implicit_value.

The default_value will be used when the option is not specified at all. The implicit_value will be used when the option is specific without a value. If a value is specified, it will override the default and implicit.

So, some code to do this could look something like this:

#include "boost/program_options.hpp"
#include <iostream>
#include <string>

using namespace std;

int main(int argc, char** argv)
{
    namespace po = boost::program_options;

    po::options_description desc("Options");
    desc.add_options()
        ("process-jpeg,e", po::value<string>()->default_value("")->implicit_value("./"), "Processes a JPEG.");

    po::variables_map vm;
    try
    {
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::notify(vm);
    } catch (po::error& e) {
        cerr << "ERROR: " << e.what() << endl << endl << desc << endl;
        return 1;
    }

    string outputDir = vm["process-jpeg"].as<string>();
    if (outputDir.empty()) {
        cout << "-e was not provided on the command line" << endl;
    } else {
        cout << "-e is using directory: " << outputDir << endl;
    }
}

Running this example code prints:

$ ./jpg_processor
-e was not provided on the command line

$ ./jpg_processor -e
-e is using directory: ./

$ ./jpg_processor -e c:\tmp
-e is using directory: c:\tmp
Slicer answered 10/8, 2015 at 15:42 Comment(2)
Latest Boost-1.59 changes this behavior. If you define implicit_value and default_value, you cannot set value e.g --argument 3. If you add --argument, implicit value is used. If not, default value is used. Also: if only implicit_value is defined and the argument does not exist, the argument value is undefined.Milone
While the documentation said so for years, and the code was "merely" fixed to match documentation, I'd be open to arguments to change both docs and code in the other directions. Opening a issue at github would be the best approach if you want.Darnelldarner

© 2022 - 2024 — McMap. All rights reserved.