CommandLine::=[<Key> [,<Key>]]
<Key>::=<Delimeter>KeyName[<Separator><Value>]
<Value> ::= { KeyValue | <QuoteChar>Quoted Key Value<QuoteChar>} ][
typedef CString CCmdLineParser_String ;
class CValsMap : public map<CCmdLineParser_String, CCmdLineParser_String> {};//存储关键字--值对
typedef CValsMap::const_iterator POSITION;//迭代器
CCmdLineParser(LPCTSTR sCmdLine = NULL, bool bCaseSensitive = false);//默认大小写不敏感
virtual ~CCmdLineParser();
bool Parse(LPCTSTR sCmdLine);//解析命令行
LPCTSTR getCmdLine() const { return m_sCmdLine; }
void setCaseSensitive(bool bSensitive) { m_bCaseSensitive = bSensitive; }
bool getCaseSensitive() const { return m_bCaseSensitive; }
const CValsMap& getVals() const { return m_ValsMap; }
// Start iterating through keys and values
POSITION getFirst() const;//第一个
// Get next key-value pair, returns empty sKey if end reached
POSITION getNext(POSITION& pos, CCmdLineParser_String& sKey, CCmdLineParser_String& sValue) const;//迭代器往后
bool isLast(POSITION& pos) const;//是否是最后一个
// TRUE if "Key" present in command line
bool HasKey(LPCTSTR sKey) const;//是否包含指定关键字
// Is "key" present in command line and have some value
bool HasVal(LPCTSTR sKey) const;//是否包含指定值
// Returns value if value was found or NULL otherwise
LPCTSTR GetVal(LPCTSTR sKey) const;//获取值
// Returns true if value was found
bool GetVal(LPCTSTR sKey, CCmdLineParser_String& sValue) const;
CValsMap::const_iterator findKey(LPCTSTR sKey) const;//查找指定关键字
CCmdLineParser_String m_sCmdLine;
static const TCHAR m_sDelimeters[];
static const TCHAR m_sValueSep[];
static const TCHAR m_sQuotes[];
const TCHAR CCmdLineParser::m_sDelimeters[] = _T("-/");//键的起始符
const TCHAR CCmdLineParser::m_sQuotes[] = _T("\""); // Can be _T("\"\'"), for instance
const TCHAR CCmdLineParser::m_sValueSep[] = _T(" :"); // Space MUST be in set 键值分隔符
// Construction/Destruction
CCmdLineParser::CCmdLineParser(LPCTSTR sCmdLine, bool bCaseSensitive)
: m_bCaseSensitive(bCaseSensitive)
CCmdLineParser::~CCmdLineParser()
bool CCmdLineParser::Parse(LPCTSTR sCmdLine)
if(!sCmdLine) return false;
const CCmdLineParser_String sEmpty;
LPCTSTR sCurrent = sCmdLine;
if(_tcslen(sCurrent) == 0) { break; } // No data left
LPCTSTR sArg = _tcspbrk(sCurrent, m_sDelimeters);
if(!sArg) break; // No delimeters found
if(_tcslen(sArg) == 0) break; // String ends with delimeter
LPCTSTR sVal = _tcspbrk(sArg, m_sValueSep);
if(sVal == NULL) { //Key ends command line
CCmdLineParser_String csKey(sArg);
m_ValsMap.insert(CValsMap::value_type(csKey, sEmpty));
} else if(sVal[0] == _T(' ') || _tcslen(sVal) == 1 ) { // Key with no value or cmdline ends with /Key:
CCmdLineParser_String csKey(sArg, sVal - sArg);
if(!csKey.IsEmpty()) { // Prevent /: case
m_ValsMap.insert(CValsMap::value_type(csKey, sEmpty));
sCurrent = _tcsinc(sVal);
} else { // Key with value
CCmdLineParser_String csKey(sArg, sVal - sArg);
LPCTSTR sQuote = _tcspbrk(sVal, m_sQuotes), sEndQuote(NULL);
if(sQuote == sVal) { // Quoted String
sEndQuote = _tcspbrk(sQuote, m_sQuotes);
sEndQuote = _tcschr(sQuote, _T(' '));
if(sEndQuote == NULL) { // No end quotes or terminating space, take rest of string
CCmdLineParser_String csVal(sQuote);
if(!csKey.IsEmpty()) { // Prevent /:val case
m_ValsMap.insert(CValsMap::value_type(csKey, csVal));//保存
} else { // End quote or space present
if(!csKey.IsEmpty()) { // Prevent /:"val" case
CCmdLineParser_String csVal(sQuote, sEndQuote - sQuote);
m_ValsMap.insert(CValsMap::value_type(csKey, csVal));
sCurrent = _tcsinc(sEndQuote);
CCmdLineParser::CValsMap::const_iterator CCmdLineParser::findKey(LPCTSTR sKey) const
CCmdLineParser_String s(sKey);
return m_ValsMap.find(s);
// TRUE if "Key" present in command line
bool CCmdLineParser::HasKey(LPCTSTR sKey) const
CValsMap::const_iterator it = findKey(sKey);
if(it == m_ValsMap.end()) return false;
// Is "key" present in command line and have some value
bool CCmdLineParser::HasVal(LPCTSTR sKey) const
CValsMap::const_iterator it = findKey(sKey);
if(it == m_ValsMap.end()) return false;
if(it->second.IsEmpty()) return false;
// Returns value if value was found or NULL otherwise
LPCTSTR CCmdLineParser::GetVal(LPCTSTR sKey) const
CValsMap::const_iterator it = findKey(sKey);
if(it == m_ValsMap.end()) return false;
return LPCTSTR(it->second);
// Returns true if value was found
bool CCmdLineParser::GetVal(LPCTSTR sKey, CCmdLineParser_String& sValue) const
CValsMap::const_iterator it = findKey(sKey);
if(it == m_ValsMap.end()) return false;
CCmdLineParser::POSITION CCmdLineParser::getFirst() const
return m_ValsMap.begin();
CCmdLineParser::POSITION CCmdLineParser::getNext(POSITION& pos, CCmdLineParser_String& sKey, CCmdLineParser_String& sValue) const
bool CCmdLineParser::isLast(POSITION& pos) const
return (pos == m_ValsMap.end());
#include "cmdlineparser.h"
int main(int argc, char* argv[])
CCmdLineParser parser(_T("/Key1 /Key2: -Key3:Val3 -Key4:\"Val 4-with/spaces/and-delimeters\" /Key5:Val5"));
ASSERT(parser.HasKey(_T("Key1")) == true);
ASSERT(parser.HasKey(_T("Key10")) == false);
ASSERT(parser.HasVal(_T("Key2")) == false);
ASSERT(parser.HasKey(_T("Key5"))==true);
_tprintf(_T("==================== Test Parser ====================\n"));
_tprintf(_T("Command line: [%s]\n"), parser.getCmdLine());//获取命令行参数
_tprintf(_T("Key1 has value: [%s]\n"), parser.GetVal(_T("Key1")));// -> []; //(empty string)
_tprintf(_T("Key2 has value: [%s]\n"), parser.GetVal(_T("Key2")));// -> [];
_tprintf(_T("Key3 has value: [%s]\n"), parser.GetVal(_T("Key3")));// -> [Val3];
_tprintf(_T("Key4 has value: [%s]\n"), parser.GetVal(_T("Key4")));// -> [Val 4-with/spaces/and-delimeters];
_tprintf(_T("Key5 has value: [%s]\n"), parser.GetVal(_T("Key5")));// -> []; //(empty string)
_tprintf(_T("\n================= Real Command Line =================\n"));
CCmdLineParser realParser(::GetCommandLine());
CCmdLineParser::POSITION pos = realParser.getFirst();
while(!realParser.isLast(pos))
realParser.getNext(pos, sKey, sVal);
_tprintf(_T("Key: [%s], Val: [%s]\n"), sKey, sVal);
本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/06/28/1231628.html,如需转载请自行联系原作者