![]() |
Command Line Parsing with TCLAP
Description: Introduction to command line parsing with TCLAP.Keywords: ecl command line parsing
Tutorial Level: BEGINNER
Contents
For a more detailed tutorial, visit the TCLAP documentation. Some common use cases are outlined below.
Initialisation
A single object is used to parse the command line. Initialise it with a few default properties. These will be used to automatically generate a --help argument.
1 // Supply a program description, argument separator (optional) and version number (optional).
2 CmdLine cmd("This is a test program to test the command line parsing facilities provided by TCLAP.");
3 // CmdLine cmd("This is a test program to test the command line parsing facilities provided by TCLAP.", ' ', "0.01");
4
Adding Arguments
Valid argument types include:
ecl::SwitchArg : simple boolean.
ecl::ValueArg : expect some value on the command line.
ecl::MultiArg : permit multiple values for an argument which get stored in a vector.
ecl::MultiSwitchArg : as above, but for booleans
ecl::UnlabeledValueArg : does not use a flag (like the arguments for copy), order is important!
ecl::UnlabeledMultiArg : reads in all remaining unlabelled args (like rm file1.txt file2.txt etc.)
Toggles/Switches
1 // Add a boolean (flag, name, description, default)
2 SwitchArg debug("d","debug","Enable debugging.", false);
3 cmd.add(debug);
You would call the above program (supposing it has name foo):
> foo -d false
Labelled
1 // Add a boolean (flag, name, description, default)
2 SwitchArg debug("d","debug","Enable debugging.", false);
3 cmd.add(debug);
4
5 // Add an integer
6 // (flag,name,description,compulsory flag,default value,type hint")
7 ValueArg<int> intArg("t","test","An integer argument for testing.",false,5,"integer");
8
9 cmd.add(intArg);
Custom ValueArg types can be used so long as they implement the >> operator.
> foo --test 3
Unlabelled
These are unlabelled (like what you do with cp my_file_here my_file_there).
1 // Not a regular option (name,description,compulsory flag,default value,type hint")
2 UnlabeledValueArg<std::string> outputDirArg("output_dir","Output directory for rectified images.",true,"./rectified","string");
3 cmd.add(outputDirArg);
> foo /home/snorri/images
Parsing the Arguments
1 cmd.parse(argc,argv);
2 bool debug = debugSwitch.getValue();
3 int test = testArg.getValue();
4 std::String output_dir = outputDirArg.getValue();
Allowing ROS to Pass
If you want to add your command line parsing program to a roslaunch, you'll need to let it know what it needs to parse and what it needs to pass... This can be achieved by the -- argument (literally means, 'ignore the rest'). An example:
1 <node name="service_relay" pkg="foo" type="service_relay" args="-r 2 --">
2 <remap from="service_relay/foo" to="/bar"/>
3 </node>
Alternatively you can prune the ros args before they get to the command line parser in the code itself:
1 #include <ros/init.h>
2
3 // ....
4
5 std::vector<std::string> myargs;
6 ros::removeROSArgs(argc, argv, myargs);
7 char** myargv = new char*[myargs.size()]; //array to emulate argv.
8 for(int i = 0, ie = myargs.size(); i < ie; ++i)
9 {
10 myargv[i] = const_cast<char*>(myargs[i].data());
11 }
12 cmd.parse(myargs.size(), myargv);