这个类能解析如下格式的参数:
-b
-h www.codeproject.com
stdafx.cpp
-temp:-7
除此以外,还可以解析以“—”或“/”打头的参数。
一般有三类参数需要解析:
作为标识的参数(例如“ls –l”),这叫空参数
有其值的参数(例如“netstat –p tcp”),这叫值参数
不带任何“-”的(例如“copy a.cpp b.cpp”),这叫默认参数。
复制代码
#include <map>
#include <string>
#define UNKNOWN_PARAM "UNKNOWN_PARAM"
#define NO_VALUE_PARAM "PARAM_NO_VALUE"
#define GENERIC_ERROR "GENERIC_ERROR"
/**
Interface that must be implemented by the objects that requires access to the
command line arguments.
@see CCommandLineParser
*/
class ICmdLineParam
{
public:
/**
Method called by the CCommandLineParser to pass the arguments and the values.
The parser calls this method to indicate the name of the arguments and/or
the values only when applicable. The '-' or '/' of the arguments are eliminated
before reach this method.
@return false only if the parser must stop, on a serious error.
true when the argument is OK or is malformed, in this second case
the function GetError must return a description, see below.
*/
virtual bool Parse(std::string argument,std::string value) = 0;
/** Method called by the CCommandLineParser to retrieve the error description.
// if an fail in command line occurs, this method must return a description of the error.
// Ex: "Inaccesible input file", "invalid type of algorithm",..,etc.
@retrun "" to indicate that no error was produced.
*/
virtual std::string GetError() = 0;
};
class CCommandLineParser
{
public:
CCommandLineParser(){m_defaultCommand = NULL;}
/**
Object that handle the default arguments. Only one can be specified.
*/
void SetDefaultCommand(ICmdLineParam* e);
/**
Objects that handle the empty arguments. Can be called how many times as necesary.
@param para name of the argument that this ICmdLineParam expect.
@e ICmdLineParam
*/
void PutEmptyCommand(std::string argument,ICmdLineParam* e);
/**
Entry that handle the values arguments. Can be called how many times as necesary.
@param para name of the argument that this ICmdLineParam expect.
@e ICmdLineParam
*/
void PutValueCommand(std::string argument,ICmdLineParam* e);
/**
Entry that handle the errors of the CCommandLineParser. Only one can be specified.
*/
void SetErrorCommand(ICmdLineParam* e);
/**
Inits the parse process.
@param argn number of arguments passed to the application.
@param argv array of string with the arguments passed to the application.
*/
bool ParseArguments(int argn,char* argv[]);
private:
ICmdLineParam* m_defaultCommand;
ICmdLineParam* m_errorCommand;
std::map<std::string,ICmdLineParam*> m_mapValueCommand;//值参数映射表
std::map<std::string,ICmdLineParam*> m_mapEmptyCommand;//空参数映射表
/**
Deletes the '-', '--', '/' of the argument.
@return <b>true</b> if the argument is not a value.
*/
bool DeleteMinus(std::string& param);
};
复制代码
复制代码
void CCommandLineParser::SetDefaultCommand(ICmdLineParam* obj)
{
m_defaultCommand = obj;
}
void CCommandLineParser::PutEmptyCommand(std::string argument,ICmdLineParam* obj)
{
m_mapEmptyCommand[argument] = obj;
}
void CCommandLineParser::PutValueCommand(std::string argument,ICmdLineParam* obj)
{
m_mapValueCommand[argument] = obj;
}
void CCommandLineParser::SetErrorCommand(ICmdLineParam* obj)
{
m_errorCommand = obj;
}
bool CCommandLineParser::ParseArguments(int argn,char* argv[])
{
bool bAllOK = true;
int i = 1; // First paramter is discarded becouse it's the execution program path.
while(i < argn )
{
std::string argument = argv[i];//当前待处理的参数
if(DeleteMinus(argument))
{
//到值参数映射表中寻找待设置的值参数
// Check if this argument requires a value.
std::map<std::string,ICmdLineParam*>::iterator it = m_mapValueCommand.find(argument);
if(it != m_mapValueCommand.end())
{//值参数表中存在
if(argv[i + 1] == NULL)
{//没有提供值
bAllOK &= m_errorCommand->Parse(NO_VALUE_PARAM,argument);
return false;
}
std::string paso = argv[i + 1];
if(DeleteMinus(paso))
{//没有提供值
bAllOK &= m_errorCommand->Parse(NO_VALUE_PARAM,argument);
return false;
}
else
{
bAllOK &= it->second->Parse(argument,paso);//解析出值
i++;
}
}
else
{//值参数表中不存在
it = m_mapEmptyCommand.find(argument);//到空参数表中寻找
if(it != m_mapEmptyCommand.end())
{//找到了
bAllOK &= it->second->Parse(argument,"");
}
else
{//用户设置的格式是”参数:值“,对这种情况进行解析
// Try to split a ":"
std::string::size_type position = argument.find_first_of(":");
if(position != std::string::npos)
{
std::string command = argument.substr(0,position);
std::string value = argument.substr(position + 1);
//到值参数映射表中寻址
std::map<std::string,ICmdLineParam*>::iterator it = m_mapValueCommand.find(command);
if(it != m_mapValueCommand.end())
{//找到
bAllOK &= it->second->Parse(command,value);
}
else
{//不存在
bAllOK &= m_errorCommand->Parse(UNKNOWN_PARAM,command);
return false;
}
}
else
{//未知参数
bAllOK &= m_errorCommand->Parse(UNKNOWN_PARAM,argument);
return false;
}
}
}
}
else
{//不是附加参数,而是默认参数
if(m_defaultCommand != NULL)
{
bAllOK &= m_defaultCommand->Parse("",argument);
}
else
{
return false;
}
}
i++;
}
//错误处理
std::string error = m_defaultCommand->GetError();
if(error != "")
{
m_errorCommand->Parse(GENERIC_ERROR,error);
return false;
}
std::map<std::string,ICmdLineParam*>::iterator it = m_mapValueCommand.begin();
while(it != m_mapValueCommand.end())
{
error = it->second->GetError();
if(error != "")
{
m_errorCommand->Parse(GENERIC_ERROR,error);
return false;
}
it++;
}
std::map<std::string,ICmdLineParam*>::iterator it2 = m_mapEmptyCommand.begin();
while(it2 != m_mapEmptyCommand.end())
{
error = it2->second->GetError();
if(error != "")
{
m_errorCommand->Parse(GENERIC_ERROR,error);
return false;
}
it2++;
}
return bAllOK;// Devuelve false si ha habido error.
}
bool CCommandLineParser::DeleteMinus(std::string& argument)
{//去掉参数前的分隔符
switch(argument[0])
{
case '/':
argument = &(argument.c_str()[1]);
return true;
case '-':
if(argument[1] == '-')
{
argument = &(argument.c_str()[2]);
}
else
{
argument = &(argument.c_str()[1]);
}
return true;
}
return false;
}
复制代码
本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/06/28/1231690.html,如需转载请自行联系原作者