Reputation: 771
I'm working on a C++ program that accepts a filename as a command line input, reads a bunch of data from that file, computes two things about the data, then exits. One of those computations must be done, but the other is much more optional, so I thought it would be neat to add a -c
flag to turn it off. Naively, I would just always assume that if the user gives two arguments, the first must toggle the computation and the second gives the filename, but this gets much more cumbersome with more flags. What is the standard practice for making rm -rf "file"
, rm -fr "file"
, and rm "file" -rf
all work as valid commands?
Upvotes: 1
Views: 465
Reputation: 54383
The desired behavior is demonstrated by the modern GNU tools that you will find in a current Linux distribution.
The old nasty behavior can be seen in the BSD tools that are provided by default on FreeBSD and OpenBSD.
The desired behavior is:
With the GNU versions of ls
you can do this:
ls -al *.c -h *.h --reverse -t -- -filename-1 -filename-2
This is very nice for command line users. It should be. We wrote it.
The BSD version of ls
will choke on that. It is very annoying to be forced to navigate back to the beginning of the command just to change some display options.
Upvotes: 0
Reputation: 45284
What is the standard practice for making rm -rf "file", rm -fr "file", and rm "file" -rf all work as valid commands?
A lot of people disagree on that, so there seems to be no standard practice, unless you're targetting a specific audience (i.e. when writing a linux-specific command-line tool, check out what "standard" utilities do).
In any case, most libraries end up given you the following options:
tar
and rm
often allow you to specify multiple flags together just as in your example's -rf
flags.gcc
, for instance, expects the output file's name after -o
. Because they expect options, they may obviously not be specified simultaneously.-o
and --output-file
) although some options, such as help or verbosity control, often have only a long name.--
option to indicate "end of options" is also convenient in case some of those trailing arguments may contain dashes.A lot of tools allow switches and options to be interleaved, but multiple trailing arguments are always at the end.
Of course, you will find commonly used tools that don't respect these conventions, such as Microsoft's cl.exe
and link.exe
. More recent tools seem to converge towards these though, including Microsoft's candle.exe
and light.exe
for WIX.
If you want to make sure you respect these guidelines (and save a lot of time), use a "standard" library, such as UNIX's getopt()
or boost's program options.
Edit: existing libraries often generate the --help
option for you using the short descriptions you give when you specify the switches and options you are expecting.
Upvotes: 3
Reputation: 133112
Use boost program options . Example:
po::options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("compression", po::value<int>(), "set compression level")
;
po::variables_map vm;
po::store(po::parse_command_line(ac, av, desc), vm);
po::notify(vm);
if (vm.count("help")) {
cout << desc << "\n";
return 1;
}
if (vm.count("compression")) {
cout << "Compression level was set to "
<< vm["compression"].as<int>() << ".\n";
} else {
cout << "Compression level was not set.\n";
}
Upvotes: 2
Reputation: 33655
Or, if you have boost, program_options does the trick... http://www.boost.org/doc/libs/1_44_0/doc/html/program_options.html
Upvotes: 0
Reputation: 36143
The standard argument-parsing function used by UNIX utilities, such as rm
, is getopt()
. Newer commands might use getopt_long()
, which handles so-called "long arguments" of more than one character (long --symbols
versus short -s
).
For an example of its use, take a look at this implementation of rm
, or just check the man page.
getopt()
has been ported to Win32/MFC. One such port is XGetOpt.
Upvotes: 1
Reputation: 4712
A Google search turns up this C++ class, called "Anyoption". It looks like it is exactly what you need. http://www.hackorama.com/anyoption/
You can always write your own parser, as well. I expect that, if nothing else, writing your own will be an excellent programming exercise, as it's not too difficult, but is not trivial.
Upvotes: 0