這是我好多年前,模仿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];
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/247031.html
標籤:C++
下一篇:關于c語言的知識點不足的地方
