Microsoft C startup code uses the following rules when interpreting arguments given on the operating system command line:
Arguments are delimited by white space, which is either a space or a tab.
A string surrounded by double quotation marks is interpreted as a single argument, regardless of white space contained within. A quoted string can be embedded in an argument. Note that the caret (^) is not recognized as an escape character or delimiter.
A double quotation mark preceded by a backslash, «, is interpreted as a literal double quotation mark («).
Backslashes are interpreted literally, unless they immediately precede a double quotation mark.
If an even number of backslashes is followed by a double quotation mark, then one backslash () is placed in the argv array for every pair of backslashes (\), and the double quotation mark («) is interpreted as a string delimiter.
If an odd number of backslashes is followed by a double quotation mark, then one backslash () is placed in the argv array for every pair of backslashes (\) and the double quotation mark is interpreted as an escape sequence by the remaining backslash, causing a literal double quotation mark («) to be placed in argv .
This list illustrates the rules above by showing the interpreted result passed to argv for several examples of command-line arguments. The output listed in the second, third, and fourth columns is from the ARGS.C program that follows the list.
|«a b c» d e||a b c||d||e|
|«ab»c» «\» d||ab»c||d|
|a\ d»e f»g h||a\||de fg||h|
|a\»b c d||a»b||c||d|
|a\\»b c» d e||a\b c||d||e|
One example of output from this program is:
What is the best way of parsing command-line arguments in C++ if the program is specified to be run like this:
Is there a library in STL to do this?
10 Answers 10
The suggestions for boost::program_options and GNU getopt are good ones.
However, for simple command line options I tend to use std::find
For example, to read the name of a file after a -f command line argument. You can also just detect if a single-word option has been passed in like -h for help.
On thing to look out for with this approach you must use std::strings as the value for std::find otherwise the equality check is performed on the pointer values.
I hope it is okay to edit this response instead adding a new one, as this is based on the original answer. I re-wrote the functions slightly and encapsulated them in a class, so here is the code. I thought it might be practical to use it that way as well:
I can suggest Templatized C++ Command Line Parser Library (some forks on GitHub are available), the API is very straightforward and (cited from the site):
the library is implemented entirely in header files making it easy to use and distribute with other software. It is licensed under the MIT License for worry free distribution.
This is an example from the manual, colored here for simplicity:
You can use GNU GetOpt (LGPL) or one of the various C++ ports, such as getoptpp (GPL).
A simple example using GetOpt of what you want (prog [-ab] input) is the following:
Yet another alternative is The Lean Mean C++ Option Parser:
It is a header-only library (just a single header file, in fact) and unlike all the other suggestions it is also freestanding, i.e. it has no dependencies whatsoever. In particular there’s no dependency on the STL. It does not even use exceptions or anything else that requires library support. This means it can be linked with plain C or other languages without introducing «foreign» libraries.
Like boost::program_options its API offers convenient direct access to options, i.e. you can write code like this
Unlike boost::program_options however this is simply using an array indexed with a (user-provided) enum. This offers the convenience of an associative container without the weight.
It’s well documented and has a company-friendly license (MIT).
TLMC++OP includes a nice formatter for usage messages that can do line-wrapping and column alignment which is useful if you’re localizing your program, because it ensures that the output will look good even in languages that have longer messages. It also saves you the nuisance of manually formatting your usage for 80 columns.
Command Line Parser Library for CLR and NetStandard
Note: the API surface has changed since v1.9.x and earlier. If you are looking for documentation on v1.9.x, please see stable-184.108.40.206
The Command Line Parser Library offers CLR applications a clean and concise API for manipulating command line arguments and related tasks, such as defining switches, options and verb commands. It allows you to display a help screen with a high degree of customization and a simple way to report syntax errors to the end user.
NOTE: Mentioned F# Support is provided via CommandLineParser.FSharp package with FSharp dependencies.
This library provides hassle free command line parsing with a constantly updated API since 2005.
- Compatible with .NET Framework 4.0+, Mono 2.1+ Profile, and .NET Core
- Doesn’t depend on other packages (No dependencies beyond standard base libraries)
- One line parsing using default singleton: CommandLine.Parser.Default.ParseArguments(. ) .
- Automatic or one line help screen generator: HelpText.AutoBuild(. ) .
- Supports —help , —version , version and help [verb] by default.
- Map to sequences (via IEnumerable and similar) and scalar types, including Enums and Nullable .
- You can also map to every type with a constructor that accepts a string (like System.Uri ).
- Define verb commands similar to git commit -a .
- Unparsing support: CommandLine.Parser.Default.FormatCommandLine (T options) .
- CommandLineParser.FSharp package is F#-friendly with support for option , see demo. NOTE: This is a separate NuGet package.
- Most of features applies with a CoC philosophy.
- C# demo: source here.
Getting Started with the Command Line Parser Library
You can utilize the parser library in several ways: