解析命令行参数,全部存入list当中,然后提供函数读取参数;
upsoft_arg_parser.h
#ifndef _ARGVS_PARSE_H_
#define _ARGVS_PARSE_H_
//
// 应用参数解析类CArgNodeList
// 创建: 2010-06-05 changym, changup@qq.com
// 修改:
//
//////////////////////////////////////////////////////////////////////
#include <list>
///////////////////////////////////////////////////////
// 参数是否有指示符-字典定义
///////////////////////////////////////////////////////
typedef enum enumHasSymbol {hsNone/*没有*/,hsOnly,hsHasValue};
typedef struct tagArgNode
{
tagArgNode(enumHasSymbol hassymbol,const char* pszsymbol,const char* pszvalue)
{
m_pszsymbol = m_pszvalue = 0;
m_hassymbol = hassymbol;
if(pszsymbol)
{
m_pszsymbol = new char[strlen(pszsymbol)+1];
strcpy(m_pszsymbol,pszsymbol);
m_pszsymbol[strlen(pszsymbol)] = '\0';
}
if(pszvalue)
{
m_pszvalue = new char[strlen(pszvalue)+1];
strcpy(m_pszvalue,pszvalue);
m_pszvalue[strlen(pszvalue)] = '\0';
}
}
~tagArgNode()
{
if(m_pszsymbol)
{
delete [] m_pszsymbol;
m_pszsymbol = NULL;
}
if(m_pszvalue)
{
delete [] m_pszvalue;
m_pszvalue = NULL;
}
}
enumHasSymbol m_hassymbol;
char* m_pszsymbol; //指示符串,不光是单个字符而且也可以是一个单词
char* m_pszvalue; //指示符值串,当hassymbol in (hsNone,hsHasValue)
//的时候有效
}ARGNODE,*PARGNODE;
//////////////////////////////////////////////
// 所有参数的集合
//
//////////////////////////////////////////////
class CArgNodeList : public list<PARGNODE>
{
public:
~CArgNodeList()
{
PARGNODE pnode = NULL;
while(!empty())
{
pnode = front();
delete pnode;
pop_front();
}
clear();
}
public:
int parser(int argc,char* argv[])
{
PARGNODE pnode = NULL;
for(int i=0;i<argc;i++)
{
char c = argv[i][0];
if(c=='-') //-符号发现
{
if(!argv[i][1])
{
//printf("-发现,非法,跳过\n");
continue;
}
if(argv[i+1]) //后续有参数
{
if(argv[i+1][0]=='-') //后续是一个新的参数
{
//printf("发现仅有指示符的参数:%s\n",argv[i]+1);
pnode = append(hsOnly,argv[i]+1,NULL);
}
else //后续是当前参数的值
{
//printf("发现有指示符而且带参数值的参数:%s-%s\n",argv[i]+1,argv[i+1]);
pnode = append(hsHasValue,argv[i]+1,argv[i+1]);
i++;
}
}
else //后续没有了参数,那当前参数就是-h之类的东西
{
//printf("发现仅有指示符的参数:%s\n",argv[i]+1);
pnode = append(hsOnly,argv[i]+1,NULL);
}
}
else
{
//printf("发现光秃秃的参数:%s\n",argv[i]);
pnode = append(hsNone,NULL,argv[i]);
}
}
return 1;
}
public:
//根据符号查找节点,用于查找 -a option || -a 这样的参数节点
PARGNODE getnode_symbol(const char* pszsymbol)
{
iterator iter = begin();
while(iter!=end())
{
if((*iter)->m_hassymbol!=hsNone) //有符号
{
if(!strcmp((*iter)->m_pszsymbol,pszsymbol))
{
return *iter;
}
}
iter++;
}
return NULL;
}
PARGNODE append(enumHasSymbol hassymbol,const char* pszsymbol,const char* pszvalue)
{
PARGNODE pnode = new ARGNODE(hassymbol,pszsymbol,pszvalue);
push_back(pnode);
return pnode;
}
//值完全匹配查找节点,用于查找 option 这样的节点用
PARGNODE getnode_value(const char* pszvalue);
//根据值的前n位查找节点,用于查找 name=value这样的节点
PARGNODE getnode_n_value(const char* pszvalue);
public:
void print()
{
printf("++++++++++++开始打印各参数节点信息++++++++++++++\n");
int i=1;
iterator iter = begin();
while(iter != end())
{
printf("第%d个参数节点:\n\t是否有指示符=%s\n\t指示符=%s\n\t值=%s\n",
i++,
(*iter)->m_hassymbol==hsNone?"无":((*iter)->m_hassymbol==hsOnly?"仅仅":"含值"),
(*iter)->m_pszsymbol?(*iter)->m_pszsymbol:"NULL",
(*iter)->m_pszvalue?(*iter)->m_pszvalue:"NULL");
iter++;
}
}
private:
};
#endif //_ARGVS_PARSE_H_
测试程序:upsoft_arg_parser_test.cpp
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include "upsoft_arg_parser.h"
int main(int argc, char* argv[])
{
printf("++++++++++++++++++changup解析测试++++++++++++++++\n");
//////////////////////////////////////////////////////////////
// 可能出现的参数形式:
// a 没有-指示
// -a 只有指示符
// -a changjr 有指示符而且指示出了值
// - 非法的-
// -a changjr=erzi 自定义的参数值
// changjr=er 直接是参数值
//////////////////////////////////////////////////////////////
// 具体的应用应该交给应用层自己去运用客户传入的参数和参数规则
//+合法性检查.
//////////////////////////////////////////////////////////////
CArgNodeList argnodelist;
argnodelist.parser(argc,argv);
argnodelist.print();
return 0;
}