C++版的循环缓冲区类(实际测试可用!)

本文介绍了一个名为CCycleBuffer的循环缓冲区类的实现与使用方法,包括初始化、写入、读取、获取长度、清空、判断是否为空或满等关键操作。通过实例代码演示了如何在不同情况下对缓冲区进行有效操作,适用于需要循环存储和读取数据的应用场景。
摘要由CSDN通过智能技术生成
[cpp]  view plain copy
  1. /* 
  2.  * CCycleBuffer.h 
  3.  * 
  4.  *  Created on: 2013-5-27 
  5.  *      Author: shiguang 
  6.  */  
  7.   
  8. #ifndef __test__CCycleBuffer__  
  9. #define __test__CCycleBuffer__  
  10. #include <stdio.h>  
  11. #include <stdlib.h>  
  12. #include <string.h>  
  13. #include <assert.h>  
  14. class CCycleBuffer  
  15. {  
  16. public:  
  17.     bool isFull();  
  18.     bool isEmpty();  
  19.     void Empty();  
  20.     int GetLength();  
  21.     CCycleBuffer(int size);  
  22.     virtual ~CCycleBuffer();  
  23.     int Write(char* buf, int count);  
  24.     int Read(char* buf, int count);  
  25. private:  
  26.     bool m_bEmpty, m_bFull;  
  27.     char * m_pBuf;  
  28.     int m_nBufSize;  
  29.     int m_nReadPos;  
  30.     int m_nWritePos;  
  31.   
  32. public:  
  33.     int GetReadPos()  
  34.     {  
  35.         return m_nReadPos;  
  36.     }  
  37.     int GetWritePos()  
  38.     {  
  39.         return m_nWritePos;  
  40.     }  
  41. };  
  42. #endif /* defined(__test__CCycleBuffer__) */  


[cpp]  view plain copy
  1. /* 
  2.  * CCycleBuffer.cpp 
  3.  * 
  4.  *  Created on: 2013-5-27 
  5.  *      Author: shiguang 
  6.  */  
  7.   
  8. #include "CCycleBuffer.h"  
  9. // 定义  
  10. CCycleBuffer::CCycleBuffer(int size)  
  11. {  
  12.     m_nBufSize = size;  
  13.     m_nReadPos = 0;  
  14.     m_nWritePos = 0;  
  15.     m_pBuf = new char[m_nBufSize];  
  16.     m_bEmpty = true;  
  17.     m_bFull = false;  
  18. }  
  19.   
  20. CCycleBuffer::~CCycleBuffer()  
  21. {  
  22.     delete[] m_pBuf;  
  23. }  
  24.   
  25. /************************************************************************/  
  26. /* 向缓冲区写入数据,返回实际写入的字节数                               */  
  27. /************************************************************************/  
  28. int CCycleBuffer::Write(char* buf, int count)  
  29. {  
  30.     if (count <= 0)  
  31.         return 0;  
  32.     m_bEmpty = false;  
  33.     // 缓冲区已满,不能继续写入  
  34.     if (m_bFull)  
  35.     {  
  36.         return 0;  
  37.     }  
  38.     else if (m_nReadPos == m_nWritePos) // 缓冲区为空时  
  39.     {  
  40.         /*                          == 内存模型 == 
  41.          (empty)             m_nReadPos                (empty) 
  42.          |----------------------------------|-----------------------------------------| 
  43.          m_nWritePos        m_nBufSize 
  44.          */  
  45.         int leftcount = m_nBufSize - m_nWritePos;  
  46.         if (leftcount > count)  
  47.         {  
  48.             memcpy(m_pBuf + m_nWritePos, buf, count);  
  49.             m_nWritePos += count;  
  50.             m_bFull = (m_nWritePos == m_nReadPos);  
  51.             return count;  
  52.         }  
  53.         else  
  54.         {  
  55.             memcpy(m_pBuf + m_nWritePos, buf, leftcount);  
  56.             m_nWritePos =  
  57.                     (m_nReadPos > count - leftcount) ?  
  58.                             count - leftcount : m_nReadPos; // 计算未写入数据大小  
  59.             memcpy(m_pBuf, buf + leftcount, m_nWritePos);  
  60.             m_bFull = (m_nWritePos == m_nReadPos);  
  61.             return leftcount + m_nWritePos;  
  62.         }  
  63.     }  
  64.     else if (m_nReadPos < m_nWritePos) // 有剩余空间可写入  
  65.     {  
  66.         /*                           == 内存模型 == 
  67.          (empty)                 (data)                     (empty) 
  68.          |-------------------|----------------------------|---------------------------| 
  69.          m_nReadPos                m_nWritePos       (leftcount) 
  70.          */  
  71.         // 剩余缓冲区大小(从写入位置到缓冲区尾)  
  72.         int leftcount = m_nBufSize - m_nWritePos;  
  73.         if (leftcount > count)   // 有足够的剩余空间存放  
  74.         {  
  75.             memcpy(m_pBuf + m_nWritePos, buf, count);  
  76.             m_nWritePos += count;  
  77.             m_bFull = (m_nReadPos == m_nWritePos);  
  78.             assert(m_nReadPos <= m_nBufSize);  
  79.             assert(m_nWritePos <= m_nBufSize);  
  80.             return count;  
  81.         }  
  82.         else       // 剩余空间不足  
  83.         {  
  84.             // 先填充满剩余空间,再回头找空间存放  
  85.             memcpy(m_pBuf + m_nWritePos, buf, leftcount);  
  86.             m_nWritePos =  
  87.                     (m_nReadPos >= count - leftcount) ?  
  88.                             count - leftcount : m_nReadPos;  
  89.             memcpy(m_pBuf, buf + leftcount, m_nWritePos);  
  90.             m_bFull = (m_nReadPos == m_nWritePos);  
  91.             assert(m_nReadPos <= m_nBufSize);  
  92.             assert(m_nWritePos <= m_nBufSize);  
  93.             return leftcount + m_nWritePos;  
  94.         }  
  95.     }  
  96.     else  
  97.     {  
  98.         /*                          == 内存模型 == 
  99.          (unread)                 (read)                     (unread) 
  100.          |-------------------|----------------------------|---------------------------| 
  101.          m_nWritePos    (leftcount)    m_nReadPos 
  102.          */  
  103.         int leftcount = m_nReadPos - m_nWritePos;  
  104.         if (leftcount > count)  
  105.         {  
  106.             // 有足够的剩余空间存放  
  107.             memcpy(m_pBuf + m_nWritePos, buf, count);  
  108.             m_nWritePos += count;  
  109.             m_bFull = (m_nReadPos == m_nWritePos);  
  110.             assert(m_nReadPos <= m_nBufSize);  
  111.             assert(m_nWritePos <= m_nBufSize);  
  112.             return count;  
  113.         }  
  114.         else  
  115.         {  
  116.             // 剩余空间不足时要丢弃后面的数据  
  117.             memcpy(m_pBuf + m_nWritePos, buf, leftcount);  
  118.             m_nWritePos += leftcount;  
  119.             m_bFull = (m_nReadPos == m_nWritePos);  
  120.             assert(m_bFull);  
  121.             assert(m_nReadPos <= m_nBufSize);  
  122.             assert(m_nWritePos <= m_nBufSize);  
  123.             return leftcount;  
  124.         }  
  125.     }  
  126. }  
  127.   
  128. /************************************************************************/  
  129. /* 从缓冲区读数据,返回实际读取的字节数                                 */  
  130. /************************************************************************/  
  131. int CCycleBuffer::Read(char* buf, int count)  
  132. {  
  133.     if (count <= 0)  
  134.         return 0;  
  135.     m_bFull = false;  
  136.     if (m_bEmpty)       // 缓冲区空,不能继续读取数据  
  137.     {  
  138.         return 0;  
  139.     }  
  140.     else if (m_nReadPos == m_nWritePos)   // 缓冲区满时  
  141.     {  
  142.         /*                          == 内存模型 == 
  143.          (data)          m_nReadPos                (data) 
  144.          |--------------------------------|--------------------------------------------| 
  145.          m_nWritePos         m_nBufSize 
  146.          */  
  147.         int leftcount = m_nBufSize - m_nReadPos;  
  148.         if (leftcount > count)  
  149.         {  
  150.             memcpy(buf, m_pBuf + m_nReadPos, count);  
  151.             m_nReadPos += count;  
  152.             m_bEmpty = (m_nReadPos == m_nWritePos);  
  153.             return count;  
  154.         }  
  155.         else  
  156.         {  
  157.             memcpy(buf, m_pBuf + m_nReadPos, leftcount);  
  158.             m_nReadPos =  
  159.                     (m_nWritePos > count - leftcount) ?  
  160.                             count - leftcount : m_nWritePos;  
  161.             memcpy(buf + leftcount, m_pBuf, m_nReadPos);  
  162.             m_bEmpty = (m_nReadPos == m_nWritePos);  
  163.             return leftcount + m_nReadPos;  
  164.         }  
  165.     }  
  166.     else if (m_nReadPos < m_nWritePos)   // 写指针在前(未读数据是连接的)  
  167.     {  
  168.         /*                          == 内存模型 == 
  169.          (read)                 (unread)                      (read) 
  170.          |-------------------|----------------------------|---------------------------| 
  171.          m_nReadPos                m_nWritePos                     m_nBufSize 
  172.          */  
  173.         int leftcount = m_nWritePos - m_nReadPos;  
  174.         int c = (leftcount > count) ? count : leftcount;  
  175.         memcpy(buf, m_pBuf + m_nReadPos, c);  
  176.         m_nReadPos += c;  
  177.         m_bEmpty = (m_nReadPos == m_nWritePos);  
  178.         assert(m_nReadPos <= m_nBufSize);  
  179.         assert(m_nWritePos <= m_nBufSize);  
  180.         return c;  
  181.     }  
  182.     else          // 读指针在前(未读数据可能是不连接的)  
  183.     {  
  184.         /*                          == 内存模型 == 
  185.          (unread)                (read)                      (unread) 
  186.          |-------------------|----------------------------|---------------------------| 
  187.          m_nWritePos                  m_nReadPos                  m_nBufSize 
  188.  
  189.          */  
  190.         int leftcount = m_nBufSize - m_nReadPos;  
  191.         if (leftcount > count)   // 未读缓冲区够大,直接读取数据  
  192.         {  
  193.             memcpy(buf, m_pBuf + m_nReadPos, count);  
  194.             m_nReadPos += count;  
  195.             m_bEmpty = (m_nReadPos == m_nWritePos);  
  196.             assert(m_nReadPos <= m_nBufSize);  
  197.             assert(m_nWritePos <= m_nBufSize);  
  198.             return count;  
  199.         }  
  200.         else       // 未读缓冲区不足,需回到缓冲区头开始读  
  201.         {  
  202.             memcpy(buf, m_pBuf + m_nReadPos, leftcount);  
  203.             m_nReadPos =  
  204.                     (m_nWritePos >= count - leftcount) ?  
  205.                             count - leftcount : m_nWritePos;  // 计算剩余未读数据大小  
  206.             memcpy(buf + leftcount, m_pBuf, m_nReadPos); // 注意目的指针位置  
  207.             m_bEmpty = (m_nReadPos == m_nWritePos);  
  208.             assert(m_nReadPos <= m_nBufSize);  
  209.             assert(m_nWritePos <= m_nBufSize);  
  210.             return leftcount + m_nReadPos;  
  211.         }  
  212.     }  
  213. }  
  214.   
  215. /************************************************************************/  
  216. /* 获取缓冲区有效数据长度                                               */  
  217. /************************************************************************/  
  218. int CCycleBuffer::GetLength()  
  219. {  
  220.     if (m_bEmpty)  
  221.     {  
  222.         return 0;  
  223.     }  
  224.     else if (m_bFull)  
  225.     {  
  226.         return m_nBufSize;  
  227.     }  
  228.     else if (m_nReadPos < m_nWritePos)  
  229.     {  
  230.         return m_nWritePos - m_nReadPos;  
  231.     }  
  232.     else  
  233.     {  
  234.         return m_nBufSize - m_nReadPos + m_nWritePos;  
  235.     }  
  236. }  
  237.   
  238. void CCycleBuffer::Empty()  
  239. {  
  240.     m_nReadPos = 0;  
  241.     m_nWritePos = 0;  
  242.     m_bEmpty = true;  
  243.     m_bFull = false;  
  244. }  
  245.   
  246. bool CCycleBuffer::isEmpty()  
  247. {  
  248.     return m_bEmpty;  
  249. }  
  250.   
  251. bool CCycleBuffer::isFull()  
  252. {  
  253.     return m_bFull;  
  254. }  


[cpp]  view plain copy
  1. /* 
  2.  * main.cpp 
  3.  * 
  4.  *  Created on: 2013-5-27 
  5.  *      Author: shiguang 
  6.  */  
  7.   
  8. #include "CCycleBuffer.h"  
  9.   
  10. int main()  
  11. {  
  12.     CCycleBuffer buffer(100);  
  13.     char* datachar = new char[40];  
  14.     char* reschar = new char[100];  
  15.   
  16.     int res = 0;  
  17.   
  18.     for (int i = 0; i < 40; ++i)  
  19.     {  
  20.         datachar[i] = i + 1;  
  21.     }  
  22.     res = buffer.Write(datachar, 40);  
  23.     printf("写入数据个数:%d\n", res);  
  24.     res = buffer.Write(datachar, 40);  
  25.     printf("写入数据个数:%d\n", res);  
  26.     res = buffer.Write(datachar, 40);  
  27.     printf("写入数据个数:%d\n", res);  
  28.     res = buffer.Write(datachar, 40);  
  29.     printf("写入数据个数:%d\n", res);  
  30.   
  31.     res = buffer.Read(reschar, 100);  
  32.     printf("读取数据个数:%d\n", res);  
  33.     for (int i = 0; i < 100; ++i)  
  34.     {  
  35.         if (i % 10 == 0)  
  36.         {  
  37.             printf("\n");  
  38.         }  
  39.         printf("%2d   ", reschar[i]);  
  40.     }  
  41.   
  42.     return 0;  
  43. }  

输出结果:

[html]  view plain copy
  1. 写入数据个数:40  
  2. 写入数据个数:40  
  3. 写入数据个数:20  
  4. 写入数据个数:0  
  5. 读取数据个数:100  
  6.   
  7.  1    2    3    4    5    6    7    8    9   10     
  8. 11   12   13   14   15   16   17   18   19   20     
  9. 21   22   23   24   25   26   27   28   29   30     
  10. 31   32   33   34   35   36   37   38   39   40     
  11.  1    2    3    4    5    6    7    8    9   10     
  12. 11   12   13   14   15   16   17   18   19   20     
  13. 21   22   23   24   25   26   27   28   29   30     
  14. 31   32   33   34   35   36   37   38   39   40     
  15.  1    2    3    4    5    6    7    8    9   10     
  16. 11   12   13   14   15   16   17   18   19   20     


源程序来自网络资料!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值