面向对象的命令行解析器,用于 C++,类似于 Windows 脚本参数对象
它与 WScript.arguments 非常相似,并且它会跟踪命名参数(选项)的使用方式。
引言
我看到关于这个主题的文章有很多。在我需要面向对象的命令行解析器时(大约两年前),这样的文章还很少。我记得我喜欢 C#/.NET 命令行参数解析器。我使用并改进了一点。(嗯,也许我也应该发布这个。)但我需要 C++ 的东西。我不是说它不存在,只是我厌倦了在 CodeProject 和其他地方搜索,然后开始编程,而且我还没有厌倦编程,所以很快就切换回搜索了。;)
我的想法是它应该像 WScript.arguments
对象一样,这是我习惯的东西,因为我在我的 WSH(即 JScript 和 VBscript)脚本中经常使用它,并且有点喜欢它。
它确实非常类似于 WScript.arguments
,此外它还跟踪命名参数(选项)的使用方式。
我希望这足以使其与其他 C++ 解析器不同,从而引起人们的兴趣,并找到它的用户。
描述
就像在 WScript.arguments
中一样,选项名称及其值必须用 ':
' 分隔(但与 WSH 不同,它不一定是 :
,可以是您选择的任何字符)
/option1:its_value
或
/option2=its_value
等等,但不能用空格或制表符。这不支持。
argument1 argument2 /option1 its_value /option2 its_value
就像在 WSH 中一样,选项可以是我们可以称之为简单的,即没有值的。
/option1 /option2
选项(命名参数)可以按任意顺序给出,并且可以与(未命名)参数混合。不支持长选项(即以两个或更多字符开头的选项,如 --)。
像 WScript.arguments
一样,此解析器在其实例化时不需要有关所需命令行参数的任何信息。这就是我添加跟踪命名参数使用情况的原因。您可以随时检索尚未访问的命名参数的数量及其列表。
这实际上是一种非常自然的方法。当解析器可以通过观察我们在代码中使用该选项来自己得出结论时,我们为什么必须告诉它我们期望哪些选项呢?
它也起到某种额外的调试信息的作用。我们不再仅仅在代码试图使用命令行中未给出的某些选项时收到警告,而是反过来也是如此。
我希望人们会发现这种方法方便且有趣。
它的其他最重要的特性
- 它是一个模板类,可以与
char
或wchar_t
一起使用。 - 当与
wchar_t
一起使用时,它能完美地处理 Unicode 字符,我一直都在测试。(在 Windows 控制台中正确打印它们是另一回事。一种方法是使用 conio.h 中的函数(如 _tcprintf)直接打印到控制台。另一种方法,请参阅我关于此主题的文章 将 Unicode 输出到 Windows 控制台。) - 如果您在 Linux 上编译它,您当然应该使用
char
。(由于一致使用 UTF-8,Linux 在处理 Unicode 字符时没有问题,因此,如果您想将它们打印到控制台,只需使用printf
或cout
即可。) - 它与
WScript.arguments
非常相似,如果您有使用WScript.arguments
的经验,您可以立即开始使用它。它有一些额外的功能(跟踪命名参数的使用),但您可以在需要时学习它们。 - 它可以在 Windows 非控制台应用程序中使用,即那些具有
_tWinMain
(即wWinMain
或WinMain
)函数而不是_tmain
(即wmain
或main
)函数的应用程序。可以在程序的任何地方实例化,而不仅仅在_tmain
函数中。 - 您可以选择选项是以 '
/
' 还是 '-
' 或任何其他字符开头。 - 您可以选择选项名称是使用 '
:
' 还是 '=
' 或任何其他字符与其值分隔。
用法
注意:我解释了所有内容,就像您将使用 TCHAR
一样。(_TCHAR
和 TCHAR
是相同的东西。我有时写 TCHAR
,有时写 _TCHAR
。我为因此而让您感到困惑而道歉。)因此字符串写成 _T("foo")
。但您当然可以直接使用 char
或 wchar_t
。在这种情况下,字符串字面量将分别写成 "foo"
和 L"foo"
。
您可能首先会尝试在示例项目中使用解析器。要在您的项目中使用它,您当然需要将我的头文件放入您的项目文件夹或您的编译器的包含路径中。
实例化
有3个类
CStlCmdLineArgs
CArgList
CStlCmdLineArgsWin
CStlCmdLineArgs
是真正的解析器。它需要在构造函数中将 argc
和 argv
作为参数传递。CArgList
使用 Windows 函数 GetCommandLine
创建该参数,而 CStlCmdLineArgsWin
通过继承和包含分别连接它们,以便您可以用最简单的方式实例化解析器。已包含 CStlCmdLineArgsWin_4.h:
CStlCmdLineArgsWin<TCHAR> cma;
由于您不依赖 argv
和 argc
,因此您可以在代码中的任何地方轻松地以这种方式实例化它。这是 Windows 应用程序最推荐的方法。
在 Linux 上,CArgList
没有意义,因此您必须直接使用 argc
和 argv
实例化 CStlCmdLineArgs
。这种方法也可以在 Windows 命令行应用程序中使用。在 Linux 上,模板参数应该是 char
而不是 TCHAR
。已包含 CStlCmdLineArgs4.h:
CStlCmdLineArgs<TCHAR> cma(argc, argv);
最基本的使用
您使用它们的方式与 WScript.arguments
相同。唯一的区别是,在 WScript.arguments
中,您会使用圆括号,而在这里您使用方括号。
您可以通过以下方式访问纯参数(即未命名参数):
cma.unnamed[0]
cma.unnamed[1]
等等。
...并且,与 WScript.arguments.unnamed
不同,cma.unnamed
从第 0 个命令行参数开始,因此 cma.unnamed[0]
给出的值与您在 _tmain
函数中检索 argv[0]
所获得的值相同。
如果索引超出范围,即如果您尝试访问比命令行上存在的参数更多的参数,它将简单地返回 NULL
。
您可以通过以下方式访问选项(即命名参数):
cma.named[_T("name_of_your_option")]
如果命令行中不存在特定选项,它将返回 NULL
。
如果选项没有给出值,它将返回空字符串。这是您检查“简单”选项(即不需要值的选项)是否存在的方式。
您还可以
查看命令行上有多少个未命名参数(您在每个程序中都需要):
cma.unnamed.size()
查看命令行上有多少个命名参数(您可能永远不会使用 ;):
cma.named.size()
高级用法 - 如果您想给用户更精确的错误消息
这是 WScript.arguments
所没有的功能。该类会跟踪您访问的命名参数。有关命令行上存在但未访问的参数信息可以通过以下方式检索:
cma.unusednamed.size()
这将给您它们的数量,并且...
cma.unusednamed.toString()
...这将以带引号并以空格分隔的单个字符串形式为您提供所有这些参数。
更多内容
到目前为止,我们已经像在 Windows 脚本中一样处理命令行选项:它们都以 '/
' 开头,并且 ':
' 将值与名称分开。这是默认设置。但类构造函数接受额外的参数,因此我们可以例如这样做:
CStlCmdLineArgsWin<TCHAR> cma('-', '=');
现在,命令行选项预计以 '-
' 开头,并且 '=
' 将其名称与其值分隔开。
假设您选择了默认设置,并且需要一个以 '/
' 开头的未命名参数,例如 /arg1
,您可以像这样转义它:/:/arg1
。如果您选择了 '-
' 并且有一个以 '-
' 开头的参数,您将像这样转义它:-:-arg1
。
历史
- 2009年3月21日:首次发布