Thursday, April 19, 2012

Simple Command-Line Argument Handling

Much of the code I write is run from the command-line and often has a large number of input parameters.  I quickly got tired of handling command-line arguments and of having to remember the ordering of parameters.

The following code makes this easier by allowing parameters to be specified as key-value pairs.  You then call command_line_get_argument(.), with the desired argument name and type.  It searches through the list of arguments supplied to the program and attempts to read them into the correct type.  If the argument doesn't exist or doesn't convert to the correct type, the function returns false.

e.g.
// some variables declared here...
bool ok = true;
ok &= command_line_get_argument( argc, argv, "-input_file",      ARGUMENT_STRING, input_filename );
ok &= command_line_get_argument( argc, argv, "-output_basename", ARGUMENT_STRING, output_basename );
ok &= command_line_get_argument( argc, argv, "-num_iterations",  ARGUMENT_INT,    &num_iterations );
ok &= command_line_get_argument( argc, argv, "-prior_weight",    ARGUMENT_FLOAT,  &prior_weight );
if( !ok ){
std::cout << "Usage:" << argv[0] << " [arguments]" << std::endl;
std::cout << "arguments:" << std::endl;
std::cout << "\t-input_file       [filename]         REQUIRED - input ground-truth image" << std::endl;
std::cout << "\t-output_basename  [partial filename] REQUIRED - base name for output files, e.g. 'test01/image0_'" << std::endl;
std::cout << "\t-num_iterations   [integer]          REQUIRED - number of iterations to perform, each is width*height mutations" << std::endl;
std::cout << "\t-prior_weight     [real]             REQUIRED - weight for regularizer" << std::endl;
return 1;
}


The 20 or so lines above replace what was initially closer to one hundred with error checking and ends up being much more readable. The programs are also nicer to work with, since they don't rely on a specific argument order.

The code for this can be downloaded from https://sites.google.com/site/jamesgregson/tmp/command_line_arguments.h. It can be used for whatever you'd like, provided it's attributed as mine.