命令行解析器






4.81/5 (34投票s)
2002年8月18日
2分钟阅读

222419

5377
一个直观且可扩展的命令行解析器类,
引言
从命令行获取参数列表是许多应用程序的常见任务。 然而,目前还没有标准解决方案(据我所知;)。所以我写了类 CCmdLineParser
,它可以从命令行解析参数,如果它们是以下列形式输入的:
- /Key
- /KeyWithValue:Value
- /KeyWithComplexValue:"Some really complex value of /KeyWithComplexValue"
当然,支持多个键、Unicode 和长(最多 32Kb)命令行。
此实现需要 MFC 或 ATL CString
类,或一些具有类似接口的克隆,以及 STL 类 map
。
用法
首先,你应该构建这个对象并调用Parse
函数(从构造函数或CCmdLineParser parser(::GetCommandLine());或
CCmdLineParser parser; parser.Parse(_T("/Key /Key2:Val /Key3:\"Complex-Value\" -Key4"));
然后,有两种处理结果的方法。你可以检查命令行中是否指定了某个特定的键
if(parser.HasKey(_T("Key")) { // Do some stuff } if(parser.HasKey(_T("Key2")) { LPCTSTR szKey2Value = parser.GetVal(_T("Key2")); // Do something with value of Key2 } LPCTSTR szKey3Value = parser.GetVal(_T("Key3")); if(szKey3Value) { // There was key "Key3" in input, } else { // No key "Key3" in input } LPCTSTR szKey4Value = parser.GetVal(_T("Key4")); // Key4 was found in input, but since no value was specified, // szKey4Value points to empty string
另一种使用方法是枚举命令行中的所有键
CString sKey, sValue; CCmdLineParser::POSITION pos = parser.getFirst(); while(!realParser.isLast(pos)) { realParser.getNext(pos, sKey, sValue); // Do something with current key and value }
定制和 "它是如何工作的"
重复的键
如果使用相同的键指定了几个不同的值,则仅存储第一个值。 因此,如果用户传递命令行/Add:One /Add:Two
,/Add:Two
将被忽略,并且不会添加到解析列表中。区分大小写/不区分大小写
默认情况下,键是不区分大小写的。因此,/KeyOne
等于 -keyONE
。这是通过在存储之前将所有键转换为小写来完成的。 如果您想更改此行为,请调用 setCaseSensitive(true)
或使用第二个参数设置为 true 的构造函数CCmdLineParser parser(::GetCommandLine(), true);
这将切换解析器到区分大小写模式,如果用户传递 -key
,那么 GetKey(_T("Key"))
将返回 false
语法
形式上,命令行应采用以下形式CommandLine::=[<Key> [,<Key>...]] <Key>::=<Delimeter>KeyName[<Separator><Value>] <Value> ::= { KeyValue | <QuoteChar>Quoted Key Value<QuoteChar>} ][ <Delimeter>::= { - | / } <Separator>::= { : } <QuoteChar>::= { " }
<Delimeter>
、<Separator>
和 <QuoteChar>
的值分别存储在静态变量 m_sDelimeters
、m_sValueSep
和 m_sQuotes
中。 如果您想更改它们(例如,允许用户使用撇号指定带引号的值),您可以在 CmdLineParser.cpp
的开头执行此操作
const TCHAR CCmdLineParser::m_sQuotes[] = _T("\"\'");注意:如果您想更改
m_sDelimeters
,空格必须是此字符串的第一个字符。 此外,如果您有自己的 CString
类,其名称与 CString
不同,您可以在 CmdLineParser.h
的开头进行更改typedef MyOwnCString CCmdLineParser_String;
就是这样! ;)