In case you haven’t noticed, I love Boost so I’m going to introduce you to its Program Options library. It is a command line options parser; it can also read options from an INI file, and it works with STL containers. It supports showing a help message, setting default values for missing options, allows multiple instances of the same option, etc. For a complete set of features, I refer you to the documentation. This post will be a short introduction.
Let’s start with some code that defines what options our program will accept:
desc.add_options()
("help", "produce help message")
("int,i", value<int>(&v)->default_value(42), "int value")
("float,f", value<float>(&f)->default_value(3.141f), "float value")
("string,s", value<string>(&s)->default_value("Vorbrodt"), "string value")
("int_list,a", value<vector<int>>(&vi), "list of int values")
("string_list,b", value<vector<string>>(&vs), "list of string values")
;
The first option invoked with --help
will display a friendly description, like this:
Allowed options:
–help produce help message
-i [ –int ] arg (=42) int value
-f [ –float ] arg (=3.14100003) float value
-s [ –string ] arg (=Vorbrodt) string value
-a [ –int_list ] arg list of int values
-b [ –string_list ] arg list of string values
Options help message.
Next is an integer value option; the first string "int,i"
means that you can specify it as either --int
or -i
on the command line. When specified, its value will be pulled into variable v
, and if not specified, the default value will be 42
. Next two options for float
and string
behave in the exact same way. The parser will throw an exception if you specify those options more than once.
Next are list
options: they allow you to specify the same option multiple times and are returned through the vi
and vs
variables which are std::vector
‘s of int
and string
.
Here is the program invocation and the output it produces:
./bin/options -i 1 -f 3.141 -s "Martin" -a 10 -a 11 -a 12 -b "Vorbrodt’s" -b "Blog"
Int value was set to 1
Float value was set to 3.141
String value was set to "Martin"
List of ints value was set to 10
List of ints value was set to 11
List of ints value was set to 12
List of strings value was set to "Vorbrodt’s"
List of strings value was set to "Blog"
Program invocation and output.
The complete source code of the program is shown below.
options.cpp:
#include <iostream>
#include <vector>
#include <string>
#include <boost/program_options.hpp>
using namespace std;
using namespace boost::program_options;
int main(int argc, char** argv)
{
int v{};
float f{};
string s{};
vector<int> vi{};
vector<string> vs{};
options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("int,i", value<int>(&v)->default_value(42), "int value")
("float,f", value<float>(&f)->default_value(3.141f), "float value")
("string,s", value<string>(&s)->default_value("Vorbrodt"), "string value")
("int_list,a", value<vector<int>>(&vi), "list of int values")
("string_list,b", value<vector<string>>(&vs), "list of string values");
variables_map vm{};
store(parse_command_line(argc, argv, desc), vm);
notify(vm);
if (vm.size() == 0 || vm.count("help"))
{
cout << desc << "\n";
return 1;
}
if(vm.count("int")) cout << "Int value was set to " << v << endl;
if(vm.count("float")) cout << "Float value was set to " << f << endl;
if(vm.count("string")) cout << "String value was set to \"" << s << "\"" << endl;
if(vm.count("int_list"))
for(auto it : vi)
cout << "List of ints value was set to " << it << endl;
if(vm.count("string_list"))
for(auto& it : vs)
cout << "List of strings value was set to \"" << it << "\"" << endl;
return 1;
}