SkillAgentSearch skills...

Argparse

Argument Parser for Modern C++

Install / Use

/learn @p-ranav/Argparse
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<p align="center"> <img height="100" src="https://i.imgur.com/oDXeMUQ.png" alt="argparse"/> </p> <p align="center"> <a href="https://github.com/p-ranav/argparse/blob/master/LICENSE"> <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="license"/> </a> <img src="https://img.shields.io/badge/version-3.2-blue.svg?cacheSeconds=2592000" alt="version"/> </p>

Highlights

  • Single header file
  • Requires C++17
  • MIT License

Table of Contents

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 .scan method 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

View on GitHub
GitHub Stars3.4k
CategoryDevelopment
Updated1d ago
Forks298

Languages

C++

Security Score

100/100

Audited on Mar 27, 2026

No findings