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 }