高性能服务器开发;C++深探

继续上一块砖,引来玉。一个命令行参数的解析类CArgNodeList

解析命令行参数,全部存入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;
}

posted on 2010-12-15 15:10 changup 阅读(1701) 评论(0)  编辑 收藏 引用 所属分类: 随想


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理