Argparse
Argument Parser for Modern C++
Install / Use
/learn @p-ranav/ArgparseREADME
Highlights
- Single header file
- Requires C++17
- MIT License
Table of Contents
- Quick Start
- Positional Arguments
- Optional Arguments
- Storing values into variables
- Negative Numbers
- Combining Positional and Optional Arguments
- Printing Help
- Adding a description and an epilog to help
- List of Arguments
- Compound Arguments
- Converting to Numeric Types
- Default Arguments
- Gathering Remaining Arguments
- Parent Parsers
- Subcommands
- Getting Argument and Subparser Instances
- Parse Known Args
- Hidden argument and alias
- ArgumentParser in bool Context
- Custom Prefix Characters
- Custom Assignment Characters
- Further Examples
- Developer Notes
- CMake Integration
- Building, Installing, and Testing
- Supported Toolchains
- Contributing
- License
Quick Start
Simply include argparse.hpp and you're good to go.
#include <argparse/argparse.hpp>
To start parsing command-line arguments, create an ArgumentParser.
argparse::ArgumentParser program("program_name");
NOTE: There is an optional second argument to the ArgumentParser which is the program version. Example: argparse::ArgumentParser program("libfoo", "1.9.0");
NOTE: There are optional third and fourth arguments to the ArgumentParser which control default arguments. Example: argparse::ArgumentParser program("libfoo", "1.9.0", default_arguments::help, false); See Default Arguments, below.
To add a new argument, simply call .add_argument(...). You can provide a variadic list of argument names that you want to group together, e.g., -v and --verbose
program.add_argument("foo");
program.add_argument("-v", "--verbose"); // parameter packing
Argparse supports a variety of argument types including positional, optional, and compound arguments. Below you can see how to configure each of these types:
Positional Arguments
Here's an example of a positional argument:
#include <argparse/argparse.hpp>
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("program_name");
program.add_argument("square")
.help("display the square of a given integer")
.scan<'i', int>();
try {
program.parse_args(argc, argv);
}
catch (const std::exception& err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
return 1;
}
auto input = program.get<int>("square");
std::cout << (input * input) << std::endl;
return 0;
}
And running the code:
foo@bar:/home/dev/$ ./main 15
225
Here's what's happening:
- The
add_argument()method is used to specify which command-line options the program is willing to accept. In this case, I’ve named it square so that it’s in line with its function. - Command-line arguments are strings. To square the argument and print the result, we need to convert this argument to a number. In order to do this, we use the
.scanmethod to convert user input into an integer. - We can get the value stored by the parser for a given argument using
parser.get<T>(key)method.
Optional Arguments
Now, let's look at optional arguments. Optional arguments start with - or --, e.g., --verbose or -a. Optional arguments can be placed anywhere in the input sequence.
argparse::ArgumentParser program("test");
program.add_argument("--verbose")
.help("increase output verbosity")
.default_value(false)
.implicit_value(true);
try {
program.parse_args(argc, argv);
}
catch (const std::exception& err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
if (program["--verbose"] == true) {
std::cout << "Verbosity enabled" << std::endl;
}
foo@bar:/home/dev/$ ./main --verbose
Verbosity enabled
Here's what's happening:
- The program is written so as to display something when --verbose is specified and display nothing when not.
- Since the argument is actually optional, no error is thrown when running the program without
--verbose. Note that by using.default_value(false), if the optional argument isn’t used, it's value is automatically set to false. - By using
.implicit_value(true), the user specifies that this option is more of a flag than something that requires a value. When the user provides the --verbose option, it's value is set to true.
Flag
When defining flag arguments, you can use the shorthand flag() which is the same as default_value(false).implicit_value(true).
argparse::ArgumentParser program("test");
program.add_argument("--verbose")
.help("increase output verbosity")
.flag();
try {
program.parse_args(argc, argv);
}
catch (const std::exception& err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
if (program["--verbose"] == true) {
std::cout << "Verbosity enabled" << std::endl;
}
Requiring optional arguments
There are scenarios where you would like to make an optional argument required. As discussed above, optional arguments either begin with - or --. You can make these types of arguments required like so:
program.add_argument("-o", "--output")
.required()
.help("specify the output file.");
If the user does not provide a value for this parameter, an exception is thrown.
Alternatively, you could provide a default value like so:
program.add_argument("-o", "--output")
.default_value(std::string("-"))
.required()
.help("specify the output file.");
Accessing optional arguments without default values
If you require an optional argument to be present but have no good default value for it, you can combine testing and accessing the argument as following:
if (auto fn = program.present("-o")) {
do_something_with(*fn);
}
Similar to get, the present method also accepts a template argument. But rather than returning T, parser.present<T>(key) returns std::optional<T>, so that when the user does not provide a value to this parameter, the return value compares equal to std::nullopt.
Deciding if the value was given by the user
If you want to know whether the user supplied a value for an argument that has a .default_value, check whether the argument .is_used().
program.add_argument("--color")
.default_value(std::string{"orange"}) // might otherwise be type const char* leading to an error when trying program.get<std::string>
.help("specify the cat's fur color");
try {
program.parse_args(argc, argv); // Example: ./main --color orange
}
catch (const std::exception& err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
auto color = program.get<std::string>("--color"); // "orange"
auto explicit_color = program.is_used("--color"); // true, user provided orange
Joining values of repeated optional arguments
You may want to allow an optional argument to be repeated and gather all values in one place.
program.add_argument("--color")
.default_value<std::vector<std::string>>({ "orange" })
.append()
.help("specify the cat's fur color");
try {
program.parse_args(argc, argv); // Example: ./main --color red --color green --color blue
}
catch (const std::exception& err) {
std
Related Skills
node-connect
339.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.9kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
339.5kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.9kCommit, push, and open a PR
