https://github.com/stdbug/argparse
Single-header C++ command line argument parser
https://github.com/stdbug/argparse
argument-parser c-plus-plus c-plus-plus-17 cpp cpp17 option-parser
Last synced: 6 months ago
JSON representation
Single-header C++ command line argument parser
- Host: GitHub
- URL: https://github.com/stdbug/argparse
- Owner: stdbug
- License: 0bsd
- Created: 2021-05-23T18:55:20.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2021-12-27T01:26:47.000Z (about 4 years ago)
- Last Synced: 2025-07-20T00:36:05.014Z (6 months ago)
- Topics: argument-parser, c-plus-plus, c-plus-plus-17, cpp, cpp17, option-parser
- Language: C++
- Homepage:
- Size: 72.3 KB
- Stars: 4
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# argparse: single-header C++ command line argument parser library
## Basic usage
Include the header
```cpp
#include
```
Declare the parser
```cpp
argparse::Parser parser;
```
Set arguments that may appear in the command line. Each `Add*` method will
return a holder that can be used to access argument values after they are parsed
```cpp
// flag, set by mentioning it among command line arguments
// ("--flag" or "-f")
// can be mentioned multiple times (e.g. "-fff")
auto flag = parser.AddFlag("flag", 'f', "Optional help string");
// integer value passed by one of these ways:
// --integer 42
// --integer=42
// -i 42
// -i42
auto integer = parser.AddArg("integer", 'i', "Some integer");
// argument that may be passed multiple times, e.g.
// --double 3.14 --double 2.71 --double 1 --double=0,1,2
auto doubles = parser.AddMultiArg("double", 'd');
// string as-is, but without a short option
auto string = parser.AddArg("string");
```
Parse arguments
```cpp
parser.ParseArgs(argc, argv);
```
Access parsed arguments via `operator*`
No check is required for flags as they only indicate the presence of the flag
marker in the command line
```cpp
if (*flag) {
std::cout << "flag was set " << *flag << " times\n";
} else {
std::cout << "flag wasn't set\n";
}
```
For non-flag arguments first check if it was set (unless a default value is set
or the argument is marked as required, see
[below](#default-and-required-values))
```cpp
if (integer) {
std::cout << "integer was set equal to " << *integer << "\n";
} else {
std::cout << "integer wasn't set\n";
}
```
Access individual multiarg entries using range-based for loop or `operator->`
```cpp
std::cout << "doubles: "
for (double x : *doubles) {
std::cout << x << "\n";
}
std::cout << "\n"
std::cout << "doubles were set " << doubles->size() << " times:\n";
for (size_t i = 0; i < doubles->size(); i++) {
std::cout << "doubles[" << i << "] = " << doubles->at(i) << "\n";
}
```
## Default and required values
Non-flag arguments can be marked as required or have a default value
```cpp
auto integer_with_default = parser.AddArg("integer").Default(42);
auto required_double = parser.AddArg("double").Required();
```
In both of these cases there is no need to check for argument presence. Any
argument with a default value will hold it even when it's not mentioned among
`argv`. If no value is provided for a required argument, then `ParseArgs` will
throw an exception
```cpp
std::cout << "integer = " << *integer_with_default << "\n";
std::cout << "double = " << *required_double << "\n";
```
## Acceptable options for arguments
A set of valid values can be provided for arguments
```cpp
parser.AddArg("integer").Options({0, 42, 256});
```
### Misusage
Make sure that provided options are compatible. Examples of incompatible
options that will result in an exception:
```cpp
// argument with a default value can't be required
// (why would you set a default value then?)
parser.AddArg("integer").Default(42).Required();
// same
parser.AddArg("integer").Required().Default(42);
```
## Custom types
By default, `argparse::Parser` supports parsing built-in numeric types (`float`,
`double`, `long double`, `short`, `int`, `long`, `long long` and their unsigned
versions), `bool` and `std::string`. To be able to parse other types one can use
C++ operators or define a specialization of `argparse::TypeTraits` template:
```cpp
std::istream& operator>>(std::istream& stream, MyType& variable) {
// implementation
}
// Required only when using Options or Default
std::ostream& operator<<(std::ostream& stream, MyType& variable) {
// implementation
}
// Required only when using Options
bool operator==(const MyType& variable1, const MyType& variable2) {
// implementation
}
namespace argparse {
// TypeTraits specialization will have higher priority over >> and == operators
template <>
class TypeTraits {
public:
static MyType FromString(const std::string& str) {
// implementation
}
// Required only when using Options or Default
static std::string ToString(const MyType& my_var) {
// implementation
}
// Required only when using Options
static bool Equal(const MyType& variable1, const MyType& variable2) {
// implementation
}
};
} // namespace argparse
int main(int argc, char* argv[]) {
argparse::Parser parser;
auto my_var = parser.AddArg("my-var").Default(MyType()).Options({MyType(1), MyType(2)});
parser.Parse(argc, argv);
}
```
A program using `argparse::Parser` with custom types having neither required
operators nor TypeTraits specialization will fail to compile
## Errors
All parsing errors will result in throwing `argparse::ArgparseError`. State of
the parser and holders (including globals) in this case is undefined.
Optionally, parser can be set to exit the program (via `exit` function)
```
parser.ExitOnFailure(exit_code, optional_usage_string);
```
## TODO
* `--help` option