项目作者: codeschlosser

项目描述 :
Single-header C++ command line argument parser
高级语言: C++
项目地址: git://github.com/codeschlosser/argparse.git
创建时间: 2021-05-23T18:55:20Z
项目社区:https://github.com/codeschlosser/argparse

开源协议:BSD Zero Clause License

下载


argparse: single-header C++ command line argument parser library

Basic usage

Include the header

  1. #include <argparse.h>

Declare the parser

  1. 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

  1. // flag, set by mentioning it among command line arguments
  2. // ("--flag" or "-f")
  3. // can be mentioned multiple times (e.g. "-fff")
  4. auto flag = parser.AddFlag("flag", 'f', "Optional help string");
  5. // integer value passed by one of these ways:
  6. // --integer 42
  7. // --integer=42
  8. // -i 42
  9. // -i42
  10. auto integer = parser.AddArg<int>("integer", 'i', "Some integer");
  11. // argument that may be passed multiple times, e.g.
  12. // --double 3.14 --double 2.71 --double 1 --double=0,1,2
  13. auto doubles = parser.AddMultiArg<double>("double", 'd');
  14. // string as-is, but without a short option
  15. auto string = parser.AddArg<std::string>("string");

Parse arguments

  1. 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

  1. if (*flag) {
  2. std::cout << "flag was set " << *flag << " times\n";
  3. } else {
  4. std::cout << "flag wasn't set\n";
  5. }

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)

  1. if (integer) {
  2. std::cout << "integer was set equal to " << *integer << "\n";
  3. } else {
  4. std::cout << "integer wasn't set\n";
  5. }

Access individual multiarg entries using range-based for loop or operator->

  1. std::cout << "doubles: "
  2. for (double x : *doubles) {
  3. std::cout << x << "\n";
  4. }
  5. std::cout << "\n"
  6. std::cout << "doubles were set " << doubles->size() << " times:\n";
  7. for (size_t i = 0; i < doubles->size(); i++) {
  8. std::cout << "doubles[" << i << "] = " << doubles->at(i) << "\n";
  9. }

Default and required values

Non-flag arguments can be marked as required or have a default value

  1. auto integer_with_default = parser.AddArg<int>("integer").Default(42);
  2. auto required_double = parser.AddArg<double>("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

  1. std::cout << "integer = " << *integer_with_default << "\n";
  2. std::cout << "double = " << *required_double << "\n";

Acceptable options for arguments

A set of valid values can be provided for arguments

  1. parser.AddArg<int>("integer").Options({0, 42, 256});

Misusage

Make sure that provided options are compatible. Examples of incompatible
options that will result in an exception:

  1. // argument with a default value can't be required
  2. // (why would you set a default value then?)
  3. parser.AddArg<int>("integer").Default(42).Required();
  4. // same
  5. parser.AddArg<int>("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:

  1. std::istream& operator>>(std::istream& stream, MyType& variable) {
  2. // implementation
  3. }
  4. // Required only when using Options or Default
  5. std::ostream& operator<<(std::ostream& stream, MyType& variable) {
  6. // implementation
  7. }
  8. // Required only when using Options
  9. bool operator==(const MyType& variable1, const MyType& variable2) {
  10. // implementation
  11. }
  12. namespace argparse {
  13. // TypeTraits specialization will have higher priority over >> and == operators
  14. template <>
  15. class TypeTraits<MyType> {
  16. public:
  17. static MyType FromString(const std::string& str) {
  18. // implementation
  19. }
  20. // Required only when using Options or Default
  21. static std::string ToString(const MyType& my_var) {
  22. // implementation
  23. }
  24. // Required only when using Options
  25. static bool Equal(const MyType& variable1, const MyType& variable2) {
  26. // implementation
  27. }
  28. };
  29. } // namespace argparse
  30. int main(int argc, char* argv[]) {
  31. argparse::Parser parser;
  32. auto my_var = parser.AddArg<MyType>("my-var").Default(MyType()).Options({MyType(1), MyType(2)});
  33. parser.Parse(argc, argv);
  34. }

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)

  1. parser.ExitOnFailure(exit_code, optional_usage_string);

TODO

  • --help option