这是我好多年前,模仿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 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];

}

`

分享一个的c++写的,模仿awk的框架类CAwkDoc的更多相关文章

  1. 分享一个手机端好用的jquery ajax分页类

    分享一个手机端好用的jquery ajax分页类 jquery-ias.min.js 1,引入jquery-ias.min.js 2,调用ajax分页 <script type="te ...

  2. 分享一个14年写的用户管理类-swift版

    AccountManager类 14年设计,从swift 0.9开始,迭代到现在swift4.0版本,总体几乎没什么改动,简单稳定. 其实现的思路主要还是借助之前net反射的经验,实现了自动保存用户信 ...

  3. 分享一个漂亮的ASP.NET MVC黑色界面框架

    插件应用架构概述 基于LCLFramework插件框架的应用由以下三个部分构成: (1)主程序:针对特定应用环境(Web.WinForm等应用环境),加载启动插件,获取插件入口,运行入口程序. (2) ...

  4. 分享一个简单的C#的通用DbHelper类(支持数据连接池)

    每次新项目的时候,都要从头去找一遍数据库工具类.这里分享一个简单实用的C#的通用DbHelper工具类,支持数据连接池. 连接池配置 <connectionStrings> <add ...

  5. 分享一个CQRS/ES架构中基于写文件的EventStore的设计思路

    最近打算用C#实现一个基于文件的EventStore. 什么是EventStore 关于什么是EventStore,如果还不清楚的朋友可以去了解下CQRS/Event Sourcing这种架构,我博客 ...

  6. 分享一个c#写的开源分布式消息队列equeue

    分享一个c#写的开源分布式消息队列equeue 前言 equeue消息队列中的专业术语 Topic Queue Producer Consumer Consumer Group Broker 集群消费 ...

  7. 分享一个自己写的MVC+EF “增删改查” 无刷新分页程序

    分享一个自己写的MVC+EF “增删改查” 无刷新分页程序 一.项目之前得添加几个组件artDialog.MVCPager.kindeditor-4.0.先上几个效果图.      1.首先建立一个数 ...

  8. [UWP]分享一个基于HSV色轮的调色板应用

    1. 前言 上一篇文章介绍了HSV色轮,这次分享一个基于HSV色轮的调色板应用,应用地址:ColorfulBox - Microsoft Store 2. 功能 ColorfulBox是Adobe 色 ...

  9. 分享一个MySQL分库分表备份脚本(原)

    分享一个MySQL分库备份脚本(原) 开发思路: 1.路径:规定备份到什么位置,把路径(先判断是否存在,不存在创建一个目录)先定义好,我的路径:/mysql/backup,每个备份用压缩提升效率,带上 ...

随机推荐

  1. html标签和body标签的区别

    首先想要总结这个问题就是因为在开发的过程中,在设置body的高度的时候,在浏览器窗口中并不起作用,一直都会显示是浏览器窗口的大小,所以想要搞清楚这面的原因. 一.前提 在页面的设计中,当我们没有为一个 ...

  2. AcWing 332. 股票交易

    大型补档计划 题目链接 \(f[i][j]\) 表示前 \(i\) 天,手里有 \(j\) 个股票挣得最多钱 买股票.枚举 \(u < i - W\) \(f[i][j] = max(f[u][ ...

  3. AcWing 295. 清理班次

    这题显然跟 区间覆盖 是一样的,而且值域在 \(1000000\) 以内,不用离散化,直接贪心求解即可. 具体地:设 \(nxt[i]\) 为从值域 \(i\) 出发,能到达最远的右端点. 一段段地跳 ...

  4. 算法——移掉K位数字使得数值最小

    给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. leetcode 解题思路:如果这个数的各个位是递增的,那么直接从最后面开始移除一定就是最最小的:如果这个数的 ...

  5. 恋爱话术库撩妹至尊VIP版

    本软件来自互联网,解锁永久至尊VIP 是一款教你撩妹密语软件.和女生聊天没有话题? 不知道怎么逗乐女生? 女生生气了不会哄? 不知道怎么让女生愿意跟你聊下去? 不知道女生对你有没有意思? 遇到不知道怎 ...

  6. 手动实现Promise.all()

    Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例. Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每 ...

  7. 基于WSL2 的 Docker Desktop 启动时 Failed to set version to docker-desktop: exit code: -1的解决方法

    在Windows 10 的 2004 版本  中, 启用 使用Docker Desktop 时 发现  根本无法启动, 偶尔 或者频繁的出错: System.InvalidOperationExcep ...

  8. 【面试专栏】Java并发编程:volatile关键字

    1.  内存模型 若一个变量在多线程环境下同时操作,则可能出现结果不一致的情况.这就是常说的缓存不一致性问题. 解决缓存不一致问题,通常有两个解决方案: 通过在总线加LOCK#锁的方式 因为CPU和其 ...

  9. gitlab+jenkins 持续部署自动化测试

    背景:为了减少测试部署时间和减少不必要的重复工作,采用持续集成的方式进行部署,当gitlab的release (测试)分支有代码变动时,自动拉取代码部署测试环境,并进行接口回归测试 优点:部署自动化, ...

  10. 自顶向下redis4.0(1)启动

    redis4.0的启动流程 目录 redis4.0的启动流程 简介 正文 全局server对象 初始化配置 初始化服务器 事件主循环 参考文献 简介 redis 在接收客户端连接之前,大概做了以下几件 ...