跨平台的命令行参数工具 — boost program_oprations
目录
1 例子
下例展示了 program_oprations 的基本用法:为程序定义了 3 个参数: help, host, port . 其中 host 与 port 分别定义了简写 h ,p 。host 是必填项, port 是有缺省值(80)的选填项,当 port 有输入时使用输入项,否则使用缺省值 ,当输入了错误的参数时会输出错误信息。
测试效果:
progma_options 库由三部分组成:
descrition
, 描述组件,用于描述允许的参数及这些参数的值。parser
, 解析组件,用于解析输入的参数与值storage
, 存储组件, 它将解析器的输出转换成 字符串表示的健与 C++ 类型的值的 map, 并提供了访问这些值的接口。
对于上例来说, program_options 所做的事情,就是使用 options_description
描述了我们期望的参数,使用 parse_command_line
解析了输入参数并使用 store
将参数存储在 variables_map
中。当我们需要使用某个参数时直接从 variables_map
中获取。
2 description 描述组件
描述组件中有三个重要的类 : option_description
, value_semantic
和 options_description
. 前两个类组和使用来描述一个参数, option_description
包含了参数的 名称 ,描述 , 以及一个指向 value_semantic
对象的指针,这个指针对象定义了参数值的类型、可被解析的值、缺省值等信息。 而 options_description
则是 option_description
的容器。
一般地,我们添加一个参数时会先创建一个 option_description
对象,再使用 options_description
的 add
方法将参数添加到容器中:
如果参数比较多的话,使用这种方法就比较麻烦了。所以 boost 有特别的添加技巧:
这看起来有点怪怪的,实际上这是对 operator( )
操作符重载的灵活运用。 options_description.add_options()
返回 options_description_easy_init
类的实例,该类重载了 "( )" 操作符,它模拟了 option_description
的构造函数,接收参数信息构造描述信息对象,添加到描述信息容器中,并返回其对象本身的引用,使其可以再次使用 "( )" 操作符来添加描述信息。
一个 option_description
实例可以分成两个部分: 语法 syntactic
和 语义 semantic
。语法信息规定用户输入参数的形式以及解析器解析的方式,包含参数名称与参数可以使用的符号(token) 的数量, 解析器会使用它将符号组成 (参数名,参数值)
这种形式的键值对,其中参数值是一组字符串( std::vector<std::string>
); 而语义信息则负责将参数值转换成合适的 C++ 类型。
2.1 语法信息
语法信息由 boost::program_options::options_description
类 和 boost::program_options::value_semantic
类的一些方法提供。句法信息包括:
参数名称
用于在程序中做变量标识参数描述
用于给用户以提示选项值可用的 token 数
将在解析时使用
如下示例:
这个示例中, help
不接受任何 token, compression
接收一个 token, verbose
可接受 0 个或 1 个 token, email
可以接受多个 token. 用户可以使用如下命令行:
2.2 语义信息
语义信息完全由 boost::program_options::value_semantic
类提供。 如下示例:
可以使用如下命令行:
在此例中, compression
将被解析成 2
, 如果没有输入此参数,那么 compression
将使用缺省值 10
。 而 email
参数则可以由多个值组合而成。
2.3 位置信息
位置参数是一种特殊的参数。如:
这里 /etc/passwd
是没有参数名的。 当然,向前文一样,给它一个参数名也是可以的:
但 boost 提供了更优雅的解决方法: positional_options_description
类。该类可以指定:
- 允许使用多少个位置参数
- 每个位置参数的名称
- 每个位置参数的众多参数中的位置
如:
例中允许使用两个位置参数,第一个位置参数是参数中的第2个参数,名称为 "output-file", 第二个位置参数是参数中的倒数第一个参数,其名称为 "input-file"
3 parsers 解析器
顾名思义,解析器的作用就是将输入的命令行解析成程序可用的 (name,value)
键值对。由前几节可以知道,这个解析器依赖的解析规则是由 描述组件
来确定的。如果不符合描述则会抛出异常。除了通过一般的描述信息来解析,还有以下几种特殊的情况:
- 参数名称使用了
简写
(或称 ="别名"= ) - 一个参数名有多个参数值的(如上例中的 email )
- 命令行中包含了
positional
信息的,见上节内容
常用的解析方法有:
program_options::parse_command_line()
,解析命令行program_options::parse_config_file()
, 解析配置文件program_options::parse_environment()
, 解析环境变量
3.1 Configuration file parser
parse_config_file
方法可以解析类似 INI
风格的配置文件。这种风格以行为单位,一行即为一组参数。当然,还有两种特殊情况:
- 以括号
[ ]
修饰的行 ,表示一个新的 section - 以
#
修饰的注释, 从#
符号开始到行结束,都为注释
例如:
这些配置与下面的配置是等价的:
//待续