I'm a bit late to the party with this, but I'll provide an updated answer. You can actually get the functionality that you want in C++ with a little work using 'getopt'. Using getopt_long()
you can create either single character options (like -c
) or named options (like --input
). You can also use getopt_long_only()
which will allow you to pass named options with only a single dash. See for example here or this answer.
Example
Here is an example that should accomplish what you're trying to do:
#include <iostream>
#include <getopt.h>
#include <map>
#include <string>
int main (int argc, char** argv)
{
// Create the variables to store your parameters
std::map<std::string, std::string> input_parameters ;
input_parameters["input"] = "default_in" ; // Storage for input
input_parameters["output"] = "default_out" ; // Storage for output
// Create variables to hold your parameters
const struct option longopts[] =
{
{"input", required_argument, 0, 'i'},
{"output", required_argument, 0, 'o'},
{0,0,0,0} // This tells getopt that this is the end
};
// Some parameters for getopt_long
int c(0);
// Get the options from the command line
while (c != -1) {
int option_index(-1) ;
// Read the next command line option
// Note here that the ':' after the 'i' and 'o' denotes that
// it requires an argument
c = getopt_long(argc, argv, "i:o:", longopts, &option_index) ;
// If the option is valid, fill the corresponding value
if ((c>0)&&(option_index>=0)) {
std::cout << option_index << std::endl;
input_parameters[longopts[option_index].name] = optarg ;
}
switch (c) {
case 'i':
// Fill input option
input_parameters["input"] = optarg ;
case 'o':
// Fill output option
input_parameters["output"] = optarg ;
case '?':
// getopt_long printed an error message
break ;
}
}
std::cout << "input = " << input_parameters["input"] << std::endl;
std::cout << "output = " << input_parameters["output"] << std::endl;
return 0 ;
}
Note that here, you would run this leaving a space between the parameter and the value you want to pass to it. This will produce the following:
$ ./myscript --input inputfile.txt --output outputfile.txt
input = inputfile.txt
output = outputfile.txt
or
$ ./myscript -i inputfile.txt -o outpufile.txt
input = inputfile.txt
output = outputfile.txt
You can also use --input
and -i
interchangeably (similarly with --output
and -o
).
Begin shameless plug (my own CLOptions code that is built around getopt)
I was actually a little disgruntled with the amount of work it took to get the full blown functionality of getopt with parameters that could be either boolean, double, int, or string. I also had to create an entirely new implementation in EVERY PROJECT! So, instead I put together a quick class called "CLOptions" so I could #include "CLOptions.h"
in my code (everything is in a single file) and now I only need one line to define each additional option. It also creates the -h
or -help
options for printing help information for you! It includes functionality for getting each parameter as either a bool, double, int, or string depending on how you define each parameter. You can take a look at it on GitHub here with an example of how the above method could be implemented. Note that the class is C++11 and will require the -std=c++11
at compile time (although if someone asks, I can try and code up a C version).
Although I haven't tried them, there's also a host of other command line programs that have been designed by other people to solve this problem (for example options or dropt). You can probably find them by googling around.