C++ 循环缓冲类

昨天看到博客园有个面试者笔试出现此题,昨天大概给出思路,今天经过思考将实现,并做出优化改进
,逻辑易懂,基本都可以看懂,经过初步测试正确。代码如下:


  1 // MindryBuffer.cpp : 定义控制台应用程序的入口点。
2 //
3
4 #include "stdafx.h"
5 #include <iostream>
6 #include <string.h>
7 using namespace std;
8
9 class CMindryBuffer
10 {
11 public:
12 CMindryBuffer(int iBufLenth = MindryBufferLenth);
13 ~CMindryBuffer(void);
14
15 int ReSize(int iBufLenth); //重置缓冲区大小
16 int Read(char * pData,int iReadDataLength); //读取指定数据
17 int Write(char * pData,int iWriteDataLength); //写入指定数据
18
19 void Clear(); //清空缓冲区
20 int GetCapicity(); //获取缓冲区容量
21 int GetWriteAvailable(); //缓冲区可写数据 可通过此函数判断缓冲区是否已满
22 int GetReadAvailable(); //缓冲区可读数据 可通过此函数判断缓冲区是否为空
23
24 private:
25 const static int MindryBufferLenth = 10; //默认缓冲区长度
26 int m_iBufLenth; //缓冲区
27 int m_iWritePos; //写入起始位置
28 int m_iReadPos; //读取起始位置
29 int m_iDataLenth; //缓冲区存放数据长度
30 char *m_PData; //缓冲区数据指针
31 };
32
33 CMindryBuffer::CMindryBuffer(int iBufLenth)
34 {
35 m_PData = NULL;
36 m_iWritePos = 0;
37 m_iReadPos = 0;
38 m_iDataLenth = 0;
39 m_iBufLenth = iBufLenth;
40 if (m_iBufLenth > 0)
41 {
42 m_PData = new char[m_iBufLenth];
43 }
44 }
45
46 CMindryBuffer::~CMindryBuffer(void)
47 {
48 if (m_PData)
49 {
50 delete [] m_PData;
51 }
52 }
53
54
55 int CMindryBuffer::Write(char * pData,int iWriteDataLength)
56 {
57 if (m_iBufLenth - m_iDataLenth == 0 || !m_PData )
58 {
59 return 0;
60 }
61
62 int iCanWriteDataLength = iWriteDataLength> GetWriteAvailable()? GetWriteAvailable():iWriteDataLength;
63
64 int iNowWriteToEndLength = m_iBufLenth - m_iWritePos;
65 if (iNowWriteToEndLength >= iCanWriteDataLength)
66 {
67 memcpy(&m_PData[m_iWritePos],pData,iCanWriteDataLength);
68 m_iWritePos += iCanWriteDataLength;
69 }
70 else
71 {
72 memcpy(&m_PData[m_iWritePos],pData,iNowWriteToEndLength);
73 memcpy(m_PData,&pData[iNowWriteToEndLength],iCanWriteDataLength - iNowWriteToEndLength);
74 m_iWritePos = iCanWriteDataLength - iCanWriteDataLength;
75 }
76 m_iDataLenth += iCanWriteDataLength;
77 return iCanWriteDataLength;
78 }
79
80 int CMindryBuffer::Read(char * pData,int iReadDataLength)
81 {
82 if (m_iDataLenth == 0)
83 {
84 return 0;
85 }
86 int iCanReadDataLength = iReadDataLength>m_iDataLenth? m_iDataLenth:iReadDataLength;
87 int iNowReadToEndLength = m_iBufLenth - m_iReadPos;
88
89 if (iNowReadToEndLength >= iCanReadDataLength)
90 {
91 memcpy(pData,&m_PData[m_iReadPos],iCanReadDataLength);
92 m_iReadPos += iCanReadDataLength;
93 }
94 else
95 {
96 memcpy(pData,&m_PData[m_iReadPos],iNowReadToEndLength);
97 memcpy(&pData[iNowReadToEndLength],m_PData,iCanReadDataLength - iNowReadToEndLength);
98
99 m_iReadPos = iCanReadDataLength - iNowReadToEndLength;
100 }
101 m_iDataLenth -= iCanReadDataLength;
102 return iCanReadDataLength;
103 }
104
105 int CMindryBuffer::ReSize(int iBufLenth)
106 {
107 if (iBufLenth > m_iBufLenth )
108 {
109 char * pData = new char[iBufLenth];
110 Read(pData ,m_iDataLenth);
111
112 delete []m_PData;
113 m_PData = pData;
114 m_iReadPos = 0;
115 m_iWritePos = m_iDataLenth;
116 m_iBufLenth = iBufLenth;
117 }
118 return m_iDataLenth;
119 }
120
121 void CMindryBuffer::Clear()
122 {
123 m_iReadPos = 0;
124 m_iWritePos = 0;
125 m_iDataLenth = 0;
126 }
127
128 int CMindryBuffer::GetCapicity()
129 {
130 return m_iBufLenth;
131 }
132
133 int CMindryBuffer::GetWriteAvailable()
134 {
135 return m_iBufLenth -m_iDataLenth;
136
137 }
138 int CMindryBuffer::GetReadAvailable()
139 {
140 return m_iDataLenth;
141 }
142
143 int _tmain(int argc, _TCHAR* argv[])
144 {
145
146 CMindryBuffer mindBuf;
147
148 int iReadLenth;
149 char buf[100];
150 mindBuf.Write("abcd",4);
151
152 iReadLenth = mindBuf.Read(buf,1);
153 buf[iReadLenth] = 0;
154 cout<<buf<<endl;
155
156 mindBuf.Write("efghi",5);
157 iReadLenth = mindBuf.Read(buf,5);
158 buf[iReadLenth] = 0;
159 cout<<buf<<endl;
160
161 mindBuf.Write("gklmn",5);
162 iReadLenth = mindBuf.Read(buf,8);
163 buf[iReadLenth] = 0;
164 cout<<buf<<endl;
165
166
167 return 0;
168 }

时间: 2024-08-30 12:03:27

C++ 循环缓冲类的相关文章

linux c++循环缓冲区模板类

一:概述 实际学习和工作中,我们经常会遇到读写大量数据的情况,这个时候我们可能就用到了循环缓冲区. 循环缓冲区在处理大量数据的时候有很大的优点,循环缓冲区在一些竞争问题上提供了一种免锁的机制,免锁的前提是,生产者和消费都只有一个的情况下,否则也要加锁. 二:循环缓冲区的实现理论如下图 三:实现代码如下所示: //CRecycleQueue.h #include<iostream> //循环缓冲区类模板 template<class T> class CRecycleQueue{ p

jvm系列(一):java类的加载机制

java类的加载机制 原文:http://www.cnblogs.com/ityouknow/p/5603287.html 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构.类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口. 类加载器并不需要等到某个

iOS -- SKSpriteNode类

SKSpriteNode类 继承自 SKNode:UIResponder:NSObject 符合 NSCoding(SKNode)NSCopying(SKNode)NSObject(NSObject) 框架  /System/Library/Frameworks/SpriteKit.framework 可用性 可用于iOS 7.0或者更晚的版本 声明于 SKSpriteNode.h 参考指南 Sprite Kit Progamming Guide 概览 重要提示:这是一个初步的API或者开发技术

iOS -- SKScene类

SKScene类 继承自 SKEffectNode:SKNode:UIResponder:NSObject 符合 NSCoding(SKNode)NSCopying(SKNode)NSObject(NSObject) 框架  /System/Library/Frameworks/SpriteKit.framework 可用性 可用于iOS 7.0或者更晚的版本 声明于 SKScene.h 参考指南 Sprite Kit Progamming Guide 概览 重要提示:这是一个初步的API或者开

iOS -- SKPhysicsWorld类

SKPhysicsWorld类 继承自 NSObject 符合 NSCodingNSObject(NSObject) 框架  /System/Library/Frameworks/SpriteKit.framework 可用性 可用于iOS 7.0或者更晚的版本 声明于 SKPhysicsWorld.h 参考指南 Sprite Kit Progamming Guide 概览 重要提示:这是一个初步的API或者开发技术文档.虽然已经审阅了本文档的技术准确性,但是它不是最终的版本.本机密信息仅适用于

C#嵌套类

嵌套类顾名思义就是类或者结构中定义的类 class Container { class Nested { Nested() { } } } <1>嵌套类的默认访问权限是private ,可以指定为public,protected,private,internal,protected internal.<2>嵌套类型可以访问外部类(包裹嵌套类的类),如果要访问外部类型,要把外部类通过构造函数传进一个实例<3>嵌套类中只能访问外部类中的静态成员,不能直接访问外部类的非静态成

一个实用的C#网页抓取类代码分享

一个实用的C# 网页抓取类 模拟蜘蛛,类中定义了超多的C#采集文章.网页抓取文章的基础技巧,下面分享代码: using System; using System.Data; using System.Configuration; using System.Net; using System.IO; using System.Text; using System.Collections.Generic; using System.Text.RegularExpressions; using Sys

类图(Rose) - Windows XP经典软件系列

最近开始了自己高级数据结构之旅,在这次旅行中,我将持续把一些高级的数据结构从理论到编码都过一遍,同时通过博客形式分享出来,希望大家指出不足之处! 二叉排序树是一种动态排序的数据结构,支持插入.删除.查找等操作,且平均时间复杂度为O(log(N)),但是普通二叉排序树不能保证树退化为一颗分支的情况,此时最坏情况下的时间复杂度为O(N).此时,平衡二叉树的产生了.平衡二叉树是一种动态调整平衡的数据结构,但理想的平衡二叉树很难,于是人们使用AVL.红黑树.Treap.伸展树等来替代平衡二叉树,这些数据

java 类对象使用

在学习反射机制时,总结一下获得类对象方式: 第一种方式:通过类本身来获得对象 Class<?> classname = this.getClass(); 或者this.class 第二种方式:通过子类的实例获取父类对象 ClassName cn = new ClassName(); UserClass = cn.getClass(); Class<?> SubUserClass = UserClass.getSuperclass(); 第三种方式:通过类名加.class获取对象 C