一个不错的命令行解析类

原文链接: Command line parser



作者所考虑的语法是:
CommandLine:: = [ < Key > [, < Key > ]]
< Key > :: =< Delimeter > KeyName[ < Separator >< Value > ]
< Value > :: = {KeyValue|<QuoteChar>QuotedKeyValue<QuoteChar>} ][
< Delimeter > :: = {-|/}
< Separator > :: = {:}
< QuoteChar > :: = {"}



typedefCStringCCmdLineParser_String;

#include
< map >
using std::map;


class CCmdLineParser
{
public:
classCValsMap:publicmap<CCmdLineParser_String,CCmdLineParser_String>{};//存储关键字--值对
typedefCValsMap::const_iteratorPOSITION;//迭代器
public:
CCmdLineParser(LPCTSTRsCmdLine
=NULL,boolbCaseSensitive=false);//默认大小写不敏感
virtual~CCmdLineParser();

boolParse(LPCTSTRsCmdLine);//解析命令行

LPCTSTRgetCmdLine()
const{returnm_sCmdLine;}

voidsetCaseSensitive(boolbSensitive){m_bCaseSensitive=bSensitive;}
boolgetCaseSensitive()const{returnm_bCaseSensitive;}

constCValsMap&getVals()const{returnm_ValsMap;}

//Startiteratingthroughkeysandvalues
POSITIONgetFirst()const;//第一个
//Getnextkey-valuepair,returnsemptysKeyifendreached
POSITIONgetNext(POSITION&pos,CCmdLineParser_String&sKey,CCmdLineParser_String&sValue)const;//迭代器往后
//justhelper;)
boolisLast(POSITION&pos)const;//是否是最后一个

//TRUEif"Key"presentincommandline
boolHasKey(LPCTSTRsKey)const;//是否包含指定关键字
//Is"key"presentincommandlineandhavesomevalue
boolHasVal(LPCTSTRsKey)const;//是否包含指定值
//ReturnsvalueifvaluewasfoundorNULLotherwise
LPCTSTRGetVal(LPCTSTRsKey)const;//获取值
//Returnstrueifvaluewasfound
boolGetVal(LPCTSTRsKey,CCmdLineParser_String&sValue)const;

private:
CValsMap::const_iteratorfindKey(LPCTSTRsKey)
const;//查找指定关键字
private:
CCmdLineParser_Stringm_sCmdLine;
CValsMapm_ValsMap;
boolm_bCaseSensitive;

staticconstTCHARm_sDelimeters[];
staticconstTCHARm_sValueSep[];
staticconstTCHARm_sQuotes[];
}
;

const TCHARCCmdLineParser::m_sDelimeters[] = _T( " -/ " ); // 键的起始符
const TCHARCCmdLineParser::m_sQuotes[] = _T( " / "" );//Canbe_T( " / " /' " ), for instance
const TCHARCCmdLineParser::m_sValueSep[] = _T( " : " ); // SpaceMUSTbeinset键值分隔符

/**/ //
// Construction/Destruction
/**/ //

CCmdLineParser::CCmdLineParser(LPCTSTRsCmdLine,
bool bCaseSensitive)
:m_bCaseSensitive(bCaseSensitive)
{
if(sCmdLine)
{
Parse(sCmdLine);
}

}


CCmdLineParser::
~ CCmdLineParser()
{
m_ValsMap.clear();
}


bool CCmdLineParser::Parse(LPCTSTRsCmdLine)
{
if(!sCmdLine)returnfalse;

m_sCmdLine
=sCmdLine;
m_ValsMap.clear();
constCCmdLineParser_StringsEmpty;

intnArgs=0;
LPCTSTRsCurrent
=sCmdLine;
while(true){
///Key:"arg"
if(_tcslen(sCurrent)==0){break;}//Nodataleft
LPCTSTRsArg=_tcspbrk(sCurrent,m_sDelimeters);
if(!sArg)break;//Nodelimetersfound
sArg=_tcsinc(sArg);
//Key:"arg"
if(_tcslen(sArg)==0)break;//Stringendswithdelimeter
LPCTSTRsVal=_tcspbrk(sArg,m_sValueSep);
if(sVal==NULL){//Keyendscommandline
CCmdLineParser_StringcsKey(sArg);
if(!m_bCaseSensitive){
csKey.MakeLower();
}

m_ValsMap.insert(CValsMap::value_type(csKey,sEmpty));
break;
}
elseif(sVal[0]==_T('')||_tcslen(sVal)==1){//Keywithnovalueorcmdlineendswith/Key:
CCmdLineParser_StringcsKey(sArg,sVal-sArg);
if(!csKey.IsEmpty()){//Prevent/:case
if(!m_bCaseSensitive){
csKey.MakeLower();
}

m_ValsMap.insert(CValsMap::value_type(csKey,sEmpty));
}

sCurrent
=_tcsinc(sVal);
continue;
}
else{//Keywithvalue
CCmdLineParser_StringcsKey(sArg,sVal-sArg);
if(!m_bCaseSensitive){
csKey.MakeLower();
}


sVal
=_tcsinc(sVal);
//"arg"
LPCTSTRsQuote=_tcspbrk(sVal,m_sQuotes),sEndQuote(NULL);
if(sQuote==sVal){//QuotedString
sQuote=_tcsinc(sVal);
sEndQuote
=_tcspbrk(sQuote,m_sQuotes);
}
else{
sQuote
=sVal;
sEndQuote
=_tcschr(sQuote,_T(''));
}


if(sEndQuote==NULL){//Noendquotesorterminatingspace,takerestofstring
CCmdLineParser_StringcsVal(sQuote);
if(!csKey.IsEmpty()){//Prevent/:valcase
m_ValsMap.insert(CValsMap::value_type(csKey,csVal));//保存
}

break;
}
else{//Endquoteorspacepresent
if(!csKey.IsEmpty()){//Prevent/:"val"case
CCmdLineParser_StringcsVal(sQuote,sEndQuote-sQuote);
m_ValsMap.insert(CValsMap::value_type(csKey,csVal));
}

sCurrent
=_tcsinc(sEndQuote);
continue;
}

}


}


return(nArgs>0);
}


CCmdLineParser::CValsMap::const_iteratorCCmdLineParser::findKey(LPCTSTRsKey)
const
{
CCmdLineParser_Strings(sKey);
if(!m_bCaseSensitive){
s.MakeLower();
}

returnm_ValsMap.find(s);
}

// TRUEif"Key"presentincommandline
bool CCmdLineParser::HasKey(LPCTSTRsKey) const
{
CValsMap::const_iteratorit
=findKey(sKey);
if(it==m_ValsMap.end())returnfalse;
returntrue;
}


// Is"key"presentincommandlineandhavesomevalue
bool CCmdLineParser::HasVal(LPCTSTRsKey) const
{
CValsMap::const_iteratorit
=findKey(sKey);
if(it==m_ValsMap.end())returnfalse;
if(it->second.IsEmpty())returnfalse;
returntrue;
}

// ReturnsvalueifvaluewasfoundorNULLotherwise
LPCTSTRCCmdLineParser::GetVal(LPCTSTRsKey) const
{
CValsMap::const_iteratorit
=findKey(sKey);
if(it==m_ValsMap.end())returnfalse;
returnLPCTSTR(it->second);
}

// Returnstrueifvaluewasfound
bool CCmdLineParser::GetVal(LPCTSTRsKey,CCmdLineParser_String & sValue) const
{
CValsMap::const_iteratorit
=findKey(sKey);
if(it==m_ValsMap.end())returnfalse;
sValue
=it->second;
returntrue;
}


CCmdLineParser::POSITIONCCmdLineParser::getFirst()
const
{
returnm_ValsMap.begin();
}

CCmdLineParser::POSITIONCCmdLineParser::getNext(POSITION
& pos,CCmdLineParser_String & sKey,CCmdLineParser_String & sValue) const
{
if(isLast(pos)){
sKey.Empty();
returnpos;
}
else{
sKey
=pos->first;
sValue
=pos->second;
pos
++;
returnpos;
}

}

// justhelper;)
bool CCmdLineParser::isLast(POSITION & pos) const
{
return(pos==m_ValsMap.end());
}



#include " stdafx.h "
#include
" cmdlineparser.h "

int main( int argc, char * argv[])
{
CCmdLineParserparser(_T(
"/Key1/Key2:-Key3:Val3-Key4:/"Val4-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(
"====================TestParser====================/n"));
_tprintf(_T(
"Commandline:[%s]/n"),parser.getCmdLine());//获取命令行参数
_tprintf(_T("Key1hasvalue:[%s]/n"),parser.GetVal(_T("Key1")));//->[];//(emptystring)
_tprintf(_T("Key2hasvalue:[%s]/n"),parser.GetVal(_T("Key2")));//->[];
_tprintf(_T("Key3hasvalue:[%s]/n"),parser.GetVal(_T("Key3")));//->[Val3];
_tprintf(_T("Key4hasvalue:[%s]/n"),parser.GetVal(_T("Key4")));//->[Val4-with/spaces/and-delimeters];
_tprintf(_T("Key5hasvalue:[%s]/n"),parser.GetVal(_T("Key5")));//->[];//(emptystring)

_tprintf(_T(
"/n=================RealCommandLine=================/n"));
CCmdLineParserrealParser(::GetCommandLine());
CCmdLineParser::POSITIONpos
=realParser.getFirst();
CStringsKey,sVal;
while(!realParser.isLast(pos))
{
realParser.getNext(pos,sKey,sVal);
_tprintf(_T(
"Key:[%s],Val:[%s]/n"),sKey,sVal);
}

system(
"pause");
return0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值