当前位置 博文首页 > 分享一个的c++写的,模仿awk的框架类CAwkDoc

    分享一个的c++写的,模仿awk的框架类CAwkDoc

    作者:皇家救星 时间:2021-01-10 12:02

    这是我好多年前,模仿awk写的。
    awk大家都比较熟悉,使用awk处理文件,读取文件,分割字段这些工作awk自己帮你实现了。
    程序员只要编写业务逻辑代码,并且awk还提供了很多常用的字符串操作函数,可以方便地调用,所以使用起来很方便。
    但awk脚本毕竟不适合开发复杂的逻辑,而且它提供的库函数也有限,不像c++,有很多第三方库可以调用。
    于是我就想到了写一个框架类,把按行读文件,分割字段这些基本功能实现了,只留下业务逻辑供开发人员自由实现


    这里用了策略模式,程序员把业务逻辑封装成为一个策略类(实现IAwkOneDualItr接口)传给CAwkDoc即可享受CAwkDoc提供的读文件功能。
    最开始考虑过使用模板方法就行,但又担心继承CAwkDoc的程序员覆盖了它的实现,所以觉得还是策略方法好。


    这是我之前用CAwkDoc实现的一个小工具:代码生成器(https://github.com/kingstarer/kingstarer/tree/master/c%2B%2B/feepacker)
    当年这个工具给项目组减轻了不少工作量,我同事们当时特别喜欢。
    可惜项目现在早就凉了,不然这个工具估计还是在用:)
    工具虽然早没用了,但这个代码生成器的思想(代码模板替换)我还是蛮喜欢的,前段时间搞java项目,写了一个curd代码生成器,还是套用了这个方法,使用代码模板思想。


    分享一下CAwkDoc的主要代码

    AwkBase.h

    #pragma once
    #include "AwkFunc.h"
    
    class CAwkDoc;
    class IAwkOneDualItr
    {
    public:
        virtual int dualBegin(CAwkDoc &Doc) = 0;
        //返回0代表正常,继续处理下一条 返回1代表退出文本处理直接到End阶段 返回-1代表处理出错,直接退出  
        virtual int dualOneLine(CAwkDoc &Doc) = 0;
        virtual int dualEnd(CAwkDoc &Doc) = 0;
    };
    
    class CAwkOneDualItrBase:public IAwkOneDualItr
    {
    public:
        virtual int dualBegin(CAwkDoc& Doc)
        {
            return 0;
        }
    
        virtual int dualEnd(CAwkDoc& Doc)
        {
            return 0;
        }
    };
    
    class CAwkDoc
    {
    public:
        typedef map<string, string> AwkMapType;
        typedef vector<string> AwkVecType;
    
    public:
        CAwkDoc(void);
        CAwkDoc(IAwkOneDualItr* lineopr, const string& filepath);
        virtual ~CAwkDoc(void);
        virtual bool run();
    
        void setFileName(const string& filepath) 
        { 
            m_filename = filepath; 
        }
    
        void setDelimer(const string delimer) 
        { 
            m_delimer = delimer; 
        }
    
        vector<string>& Parts()
        {
            return m_vecParts;
        }
    
        void setStrParam(const string& paramname, const string& paramvalue);
        string& getStrParam(const string& paramname);
    
        AwkVecType& getVecParam(const string& paramname);
        AwkMapType& getMapParam(const string& paramname);
    
    public:
    
        int m_nf;
        int m_nr;
        string m_filename;
        string m_line;
        string m_delimer;
        vector<string> m_vecParts;
    
    
        map<string, string> m_strParams;
        map< string, AwkMapType > m_mpParams;
        map< string, AwkVecType > m_vecParams;
    
    public:
    
        IAwkOneDualItr *m_lineopr;
    };
    

    AwkBase.cpp

    #include "stdafx.h"
    #include "AwkBase.h"
    
    CAwkDoc::CAwkDoc(void)
    {
        m_delimer = " ";
        m_nf = m_nr = 0;
        m_lineopr = NULL;
    }
    
    CAwkDoc::CAwkDoc(IAwkOneDualItr* lineopr, const string& filepath):
    m_lineopr(lineopr), m_filename(filepath)
    {
        m_nf = m_nr = 0; 
        m_delimer = " ";
    }
    
    CAwkDoc::~CAwkDoc(void)
    {
    }
    
    
    bool CAwkDoc::run()
    {
        //读取文件
        string inparamStr = FileToString(m_filename);
    
    
        //将文件分行
        vector<string> vecLines;
        SplitStr(inparamStr, "\n", vecLines);
    
        if (vecLines.size() == 0)
        {
            cerr << "ERR: 文件(" <<  m_filename << ")为空或不存在!" << endl;
            return false;
        }
    
        assert(m_lineopr != NULL);
        m_lineopr->dualBegin(*this);
    
        for (size_t i = 0; i < vecLines.size(); i++)
        {
            m_line = vecLines[i];
            if (m_line == "")
            {
                continue;
            }
    
    
            //删除多余空格(为后面分割做准备)
            string theline = m_line;
            //constrictSpace(theline);
    
            m_nr++;
            m_nf = SplitStr(theline, m_delimer, m_vecParts);
    
            if (m_vecParts.size() < 20)
            {
                m_vecParts.resize(20);
            }
    
            int ret = m_lineopr->dualOneLine(*this);
    
            //1是正常结束 -1是异常结束
            if ( ret == 1 )
            {
                break;
            }
            else if ( ret == -1 )
            {
                return false;
            }
        }
    
        m_lineopr->dualEnd(*this);
    
        return true;
    }
    
    void CAwkDoc::setStrParam(const string& paramname, const string& paramvalue)
    {
        m_strParams[paramname] = paramvalue;
    }
    
    string& CAwkDoc::getStrParam(const string& paramname)
    {
        return m_strParams[paramname];
    }
    
    下一篇:没有了