Is there a really effective way of dealing with command line parameters in C++?
What I'm doing below feels completely amateurish, and I can't imagine this is how command line parameters are really handled (atoi, hard-coded argc checks) in professional software.
// Command line usage: sum num1 num2 int main(int argc, char *argv[]) { if (argc < 3) { cout << "Usage: " << argv[0] << " num1 num2\n"; exit(1); }
int a = atoi(argv[1]); int b = atoi(argv[2]); int sum = a + b;
cout << "Sum: " << sum << "\n";
return 0; }
It's a bit too big to include in a Stack Overflow answer, but I made a library for defining commands lines declaratively. It takes advantage of the the C++14 ability to build up a class constructor by giving initial values to each member variable.
The library is mostly a base class. To define your command syntax, you declare a struct that derives from it. Here's a sample:
The
Argument
,Option
, andAlias
class templates are declared in the scope of theCommandLine
base class, and you can specialize them for your own types. Each one takes thethis
pointer, the option name, the default value, and a description for use in printing the command synopsis/usage.I'm still looking to eliminate the need to sprinkle all the
this
pointers in there, but I haven't found a way to do it without introducing macros. Those pointers allow each member to register itself with the tables in the base class that drive the parsing.Once you have an instance, there are several overloads of a method to parse the input from a string or a
main
-style argument vector. The parser handles both Windows-style and Unix-style option syntax.Once it's parsed, you can access the value of any of the options using
operator()
:The whole library is only about 300 lines (excluding tests). The instances are a bit bloaty, since the parsing tables are part of the instance (rather than the class). But you generally only need one instance per program, and the convenience of this purely declarative approach is pretty powerful, and an instance can be reset simply by parsing new input.
You could use an already created library for this
http://www.boost.org/doc/libs/1_44_0/doc/html/program_options.html
I am using getopt() under windows/mingw :
if this is linux/unix then the standard one to use is gnu getopt
http://www.gnu.org/s/libc/manual/html_node/Getopt.html
You probably want to use an external library for that. There are many to chose from.
Boost has a very feature-rich (as usual) library Boost Program Options.
My personal favorite for the last few years has been TCLAP -- purely templated, hence no library or linking, automated '--help' generation and other goodies. See the simplest example from the docs.
I would recommend always using boost
lexical_cast<>
in place of junk likeatoi
,atof
, etc.http://www.boost.org/doc/libs/release/libs/conversion/lexical_cast.htm
Other than that your code okay for simple stuff.