jarro2783/cxxopts
GitHub: jarro2783/cxxopts
一个轻量级的仅头文件 C++ 命令行选项解析库,支持 GNU 风格语法、位置参数和类型安全的参数读取。
Stars: 4788 | Forks: 648
[](https://github.com/jarro2783/cxxopts/actions/workflows/cmake.yml)
[](https://conan.io/center/recipes/cxxopts)
[](https://vcpkg.io/en/package/cxxopts)
[](https://github.com/jarro2783/cxxopts/releases)
[](https://github.com/jarro2783/cxxopts)
[](https://github.com/fffaraz/awesome-cpp)
[](https://formulae.brew.sh/formula/cxxopts)
[](./LICENSE)
# 发布版本
请注意,`master` 分支通常是在进行中的工作,您可能需要使用一个
带标签的发布版本。
## Version 3 的破坏性更改
如果您使用过 Version 2,那么在 Version 3 中有一些破坏性更改
您需要了解。如果您是 `cxxopts` 的新手,可以跳过本
章节。
解析器不再修改其参数,因此您可以传递 const 的 `argc` 和
`argv`,并且预期它们不会被更改。
`ParseResult` 对象不再依赖于解析器。因此,它可以被返回
到解析器外部的作用域中并且仍然有效。现在输入不会被
修改,`ParseResult` 会存储未匹配参数的列表。可以像下面这样
检索它们:
```
auto result = options.parse(argc, argv);
result.unmatched(); // get the unmatched arguments
```
# 快速入门
这是一个轻量级的 C++ 选项解析库,支持标准的 GNU
风格语法选项。
选项可以按以下方式给出:
```
--long
--long=argument
--long argument
-a
-ab
-abc argument
```
其中 c 接收一个参数,而 a 和 b 不接收。
此外,`--` 之后的任何内容都将被解析为位置参数。
## 基础
```
#include
```
创建一个 `cxxopts::Options` 实例。
```
cxxopts::Options options("MyProgram", "One line description of MyProgram");
```
然后使用 `add_options`。
```
options.add_options()
("d,debug", "Enable debugging") // a bool parameter
("i,integer", "Int param", cxxopts::value())
("f,file", "File name", cxxopts::value())
("v,verbose", "Verbose output", cxxopts::value()->default_value("false"))
;
```
选项通过一个长选项和一个可选的短选项来声明。必须
提供描述。第三个参数是值,如果省略,则为布尔值。
只要类型可以通过 operator>> 解析,就可以提供任何类型。
要解析命令行,请执行:
```
auto result = options.parse(argc, argv);
```
要检索选项,请使用 `result.count("option")` 来获取它出现的
次数,并使用
```
result["opt"].as()
```
来获取它的值。如果 "opt" 不存在,或者类型不正确,那么将
抛出异常。
## 无法识别的参数
您可以允许跳过无法识别的参数。这适用于未解析到另一个选项的
位置参数,以及不匹配您指定的参数的 `--`
参数。这通过调用以下方法来完成:
```
options.allow_unrecognised_options();
```
并且在结果对象中,可以使用以下方法检索它们:
```
result.unmatched()
```
## 异常
异常情况会抛出 C++ 异常。有两种类型的
异常:定义选项时的错误,以及解析参数
列表时的错误。所有异常都派生自 `cxxopts::exceptions::exception`。定义
选项的错误派生自 `cxxopts::exceptions::specification`,而解析
参数的错误派生自 `cxxopts::exceptions::parsing`。
所有异常都定义了一个 `what()` 函数,用于获取解释该错误的
可打印字符串。
## 帮助组
可以将选项放置到组中,以便显示帮助信息。
要将选项放置在组中,请将组作为字符串传递给 `add_options`。然后,在显示帮助时,`help` 默认会打印所有组的帮助信息。如果您只想打印特定组的帮助信息,请将要显示的组作为 vector 传递给 `help` 函数。
## 位置参数
位置参数是指那些没有前导标志给出的参数,可以与
非位置参数一起使用。可以有多个位置参数,
并且最后一个位置参数可以是 container 类型,以保存所有剩余位置参数的列表。
要设置位置参数,首先声明选项,然后将
这些参数中的一部分配置为位置参数,如下所示:
```
options.add_options()
("script", "The script file to execute", cxxopts::value())
("server", "The server to execute on", cxxopts::value())
("filenames", "The filename(s) to process", cxxopts::value>());
options.parse_positional({"script", "server", "filenames"});
// Parse options the usual way
options.parse(argc, argv);
```
注意:`parse_positional` 默认使用函数调用中提供的参数替换现有的位置参数。要追加到现有的位置参数列表中,请使用 `cxxopts::PositionalMode::Append`。
```
options.parse_positional("another_option", cxxopts::PositionalMode::Append);
```
例如,解析以下参数:
```
my_script.py my_server.com file1.txt file2.txt file3.txt
```
将得到如下表所示的已解析参数:
| 字段 | 值 |
| ------------- | ----------------------------------------- |
| `"script"` | `"my_script.py"` |
| `"server"` | `"my_server.com"` |
| `"filenames"` | `{"file1.txt", "file2.txt", "file3.txt"}` |
## 默认值和隐式值
可以在声明选项时指定默认值或隐式值,或者两者兼有。
默认值是当选项未在命令行中指定时
所采用的值。以下为选项指定默认值:
```
cxxopts::value()->default_value("value")
```
隐式值是当选项在命令行中给出
但不带参数时所采用的值。以下指定隐式值:
```
cxxopts::value()->implicit_value("implicit")
```
如果一个选项两者都有,那么不指定它将得到值 `"value"`,
在命令行中写为 `--option` 将得到值 `"implicit"`,
而写为 `--option=another` 将使其值为 `"another"`。
请注意,如果 `option` 具有隐式值,则指定 `--option another` 将不起作用。您必须使用 `=` 语法——`--option=another` 或 `-o=another`(假设 `o` 是该选项的短名称)。这是因为不需要参数。因此,没有好的方法来确定下一个字符串是选项的参数还是位置参数。
请注意,默认值和隐式值始终作为字符串存储,
无论您希望将其存储为什么类型。它将被解析,
就像在命令行中给出一样。
默认值不会被 `Options::count` 计算。
### 禁用参数的隐式值
您可以使用以下语法指定一个不允许指定参数的选项。
```
cxxopts::value()->implicit_value("true", cxxopts::ImplicitArgPolicy::Disabled)
```
在这种情况下,将选项指定为 `--option=` 是不允许的,并且会抛出 `specified_disabled_args` 异常。请注意,对于隐式值,不支持 `--option value`。它将被视为位置参数/未匹配的参数。
## 布尔值
布尔选项的默认隐式值为 `"true"`,该值可以被
覆盖。其效果是,单独写 `-o` 会将选项 `o` 设置为
`true`。但是,也可以使用 `=value` 通过各种字符串来编写它们。
没有办法区分位置参数和
布尔值后面的值,因此我们选择将它们作为位置参数,
因此,`-o false` 不起作用。
## `std::vector` 值
支持将值列表解析为 `std::vector`,前提是 `T`
可以被解析。为了分隔列表中的单个值,使用了 define 符号 `CXXOPTS_VECTOR_DELIMITER`,
其默认值为 ','。确保您在值之间不使用空格
(除非整个列表加了双引号),因为它们会被解释为
下一个命令行选项。以下是一个可以解析为
`std::vector` 的命令行选项示例:
```
--my_list=1,-2.1,3,4.5
```
如果值列表加了引号,则可以包含空格。例如:
```
--my_list="review,memory sanitize,build help,reformat"
```
这将分别被解析为 `review`、`memory sanitize`、`build help` 和 `reformat`。
## 多次指定的选项
同一个选项可以指定多次,带有不同的参数,所有这些参数都将
按出现的顺序记录。一个例子:
```
--use train --use bus --use ferry
```
这通过为选项使用 value 的 vector 来实现支持:
```
options.add_options()
("use", "Usable means of transport", cxxopts::value>())
```
## 自定义帮助
帮助信息第一行程序名称后的字符串可以
通过调用 `options.custom_help` 完全替换。请注意,您可能
还需要通过调用 `options.positional_help` 来覆盖位置帮助信息。
## 示例
将所有内容放在一起:
```
#include
#include "cxxopts.hpp"
int main(int argc, char** argv)
{
cxxopts::Options options("test", "A brief description");
options.add_options()
("b,bar", "Param bar", cxxopts::value())
("d,debug", "Enable debugging", cxxopts::value()->default_value("false"))
("f,foo", "Param foo", cxxopts::value()->default_value("10"))
("h,help", "Print usage")
;
auto result = options.parse(argc, argv);
if (result.count("help"))
{
std::cout << options.help() << std::endl;
exit(0);
}
bool debug = result["debug"].as();
std::string bar;
if (result.count("bar"))
bar = result["bar"].as();
int foo = result["foo"].as();
return 0;
}
```
# 链接
这是一个仅包含头文件的库。
# 环境要求
唯一的构建要求是支持 C++11 特性的 C++ 编译器,例如:
* regex
* constexpr
* default constructors
已知 GCC >= 4.9 或带有 libc++ 的 clang >= 3.1 可以正常工作。
已知以下编译器无法正常工作:
* MSVC 2013标签:Bash脚本, C++, Header Only, SOC Prime, 命令行解析, 开发工具, 数据擦除, 轻量级库