环形buffer缓冲区
#include <stdio.h>
#include <string.h>
#include <malloc.h> struct CircleBuf
{
char *pFirst;//指向循环表开始的位置
char *pLast;//指向循环表结尾的位置
char *plSave;//指向最后一个存数据的后一位,没有数据为NULL,或与pfsave相等
char *pfSave;//指向第一个存数据的位置,没有数据为NULL,或与plsave相等
int iSize;//循环表的大小
int iDataNum;//存数据的大小
}; int InitCircleBuf(struct CircleBuf *buf, const int bufSize)
//初始化缓冲区。buf为目标缓冲区。字节数为bufSize,能存储bufSize 个字符
//操作成功返回1,操作失败返回0.
{
buf->pFirst = (char*)malloc((bufSize + )*(sizeof(char)));//初始化CiecleLink
if(NULL == buf->pFirst)
{
printf("\nMemory allocation failure !\n");
return ;
}
buf->iSize = bufSize;
buf->iDataNum = ;
buf->pfSave = NULL;
buf->plSave = NULL;
buf->pLast = buf->pFirst + buf->iSize;
return ;
} void DestroyCircleBuf(struct CircleBuf *buf)
//销毁环形缓冲区
{
free(buf->pFirst);
buf->iDataNum = ;
buf->iSize = ;
buf->pFirst = NULL;
buf->pLast = NULL;
buf->plSave = NULL;
buf->pfSave = NULL;
} void ClearCircleBuf(struct CircleBuf *buf)
//清空环形缓冲区
{
buf->plSave = NULL;
buf->pfSave = NULL;
buf->iDataNum = ;
} int InCircleBuf(struct CircleBuf *buf, char *str, int length)
//向循环表存入数据。buf为目标循环表,str为源字符串地址,存入的字节数为length
//操作成功返回 1, 操作失败返回 0
{
int i;
int j;
int len;
int lengthtem;
len = strlen(str);
if(len < length)
{
printf("the length is longer then the size of str !\n");
return ; } if((NULL == buf->pfSave) &&(NULL == buf->plSave))//CircleBuf为空时
{
if(length > (buf->iSize - ))
{
printf("length is longer then the size of Circlebuf !\n");
return ;
}
else
{ strncpy(buf->pFirst, str, length);
buf->pfSave = buf->pFirst;
buf->plSave = buf->pfSave + length;
buf->iDataNum += length; }
}
else if(buf->pfSave <= buf->plSave)//pfsave小于或等于plsave,存数据没有超过结尾处
{ if(length < (buf->pLast - buf->plSave + ))//存数据的length没有达到CircleBuf结尾
{ strncpy(buf->plSave, str, length);
buf->iDataNum += length;
buf->plSave += length;
}
else if(length == (buf->pLast - buf->plSave + ))//存数据的length刚好到CircleBuf结尾处
{ if(buf->pfSave > buf->pFirst)
{
strncpy(buf->plSave, str, length);
buf->iDataNum += length;
buf->plSave = buf->pFirst;
}
else
{
printf("the length is longer then the unused space !\n");
return ;
}
}
else //存数据的length长度超过CircleBuf结尾
{ if(length > ((buf->pLast - buf->plSave)+(buf->pfSave - buf->pFirst)))
//存数据的length大于剩余空间大小
{
printf("length is too long then the unused space!\n");
return ;
}
else //存数据的length小于剩余空间大小,将length长度数据分两次存
{ lengthtem = length - (buf->pLast - buf->plSave + );
for(i=; i<(buf->pLast - buf->plSave + ); i++)
{
*(buf->plSave + i) = str[i]; }
buf->plSave = buf->pFirst; for(j=; j<lengthtem; j++)
{
*(buf->plSave + j) = str[i + j]; } buf->plSave += j;
buf->iDataNum += length; }
}
}
else if(buf->pfSave > buf->plSave)//pfsave大于plsave,存数据超过结尾处,至少绕了一圈
{
if(length > (buf->pfSave - buf->plSave))//存数据的length大于剩余空间大小
{
printf("length is too long then the unsued space!\n");
return ;
}
else
{
strncpy(buf->plSave, str, length);
buf->iDataNum += length;
buf->plSave += length;
}
}
return ;
} int OutCircleBuf(char *str, struct CircleBuf *buf, int length)
//从循环表中取数据。 str为目标字符串地址, buf为源循环表, 取出的字节数为length
//操作成功返回 1, 操作失败返回 0
{
int i;
int j;
int lengthtem; if((NULL == buf->pfSave) &&(NULL == buf->plSave))//CircleBuf为空
{
printf("the Circlebuf is empty !\n");
return ;
} if(buf->pfSave < buf->plSave)//pfsave小于plsave,存的数据没有超过结尾
{
if((buf->pfSave + length) > buf->plSave)
{
printf("length is longer then the used of Circlebuf !\n");
return ;
}
else
{
strncpy(str, buf->pfSave, length);
buf->pfSave += length;
buf->iDataNum -= length;
}
}
else if(buf->pfSave == buf->plSave)//pfsave等于plsave,CircleBuf为空
{
printf("there is no data in Circlebuf !\n");
return ;
}
else if(buf->pfSave > buf->plSave)//pfsave大于plsave,存的数据超过结尾,至少绕了一圈
{ if(length < (buf->pLast - buf->pfSave + ))//取数据的length没到结尾
{
strncpy(str, buf->pfSave, length);
buf->pfSave += length;
buf->iDataNum -= length;
}
else if(length == (buf->pLast - buf->pfSave + ))//取数据的length刚好达到结尾处
{
strncpy(str, buf->pfSave, length);
buf->pfSave = buf->pFirst;
buf->iDataNum -= length;
}
else //取数据的length超过结尾
{ if((length - (buf->pLast - buf->pfSave + )) > (buf->plSave - buf->pFirst))
//取数据的length大于剩余数据的大小
{
printf("%d\n",(buf->plSave - buf->pFirst));
printf("the used data is shorter then length !\n");
return ;
}
else //取数据的length小于剩余数据的大小,将数据分开两次取出来
{
lengthtem = length - (buf->pLast - buf->pfSave + );
for(i=; i<(buf->pLast - buf->pfSave + ); i++)
{
str[i] = *(buf->pfSave +i);
}
buf->pfSave = buf->pFirst;
for(j=; j<lengthtem; j++)
{
str[i + j] = *(buf->pfSave + j);
}
buf->pfSave += j;
buf->iDataNum -= length;
}
}
}
str[length] = '\0';
return ;
} int CalDataNumCB(struct CircleBuf *buf)
//计算循环表的数据个数。buf为目标循环表
//返回已存放数据的字节数
{
return buf->iDataNum;
} int CalSpaceNumCB(struct CircleBuf *buf)
//计算循环表的剩余空间大小。 buf为目标循环表
//返回剩余空间字节数
{
return (buf->iSize - buf->iDataNum);
} int OutCBtoFile(char *filename, struct CircleBuf *buf)
//将循环表中所有的数据都存到所给的文件中,filename为目标文件的路径及名称,buf为源循环表。
//操作成功返回 1, 操作失败返回 0
{
FILE *fp;
int i;
int length;
char ch[];
if(NULL == (fp = fopen(filename, "wt+")))//判断文件是否打开
{
printf("can't open %s !\n", filename);
return ;
}
length = CalDataNumCB(buf); for(i=; i<length; i++) //将全部数据读入文件中
{
OutCircleBuf(ch, buf, );
printf("%d %c \n", strlen(ch), ch[]);
fwrite(ch, , , fp); } fclose(fp);
return ;
} int InCBfromFile(struct CircleBuf *buf, char *filename)
//将文件中的数据读到循环链表中,clink为目标链表,filename为源文件的路径及名称。
//操作失败返回0, 文件数据全部存储完毕返回1, clink空间不足,只存入部分数据返回-1
{
FILE *fp;
int length;
char ch; if(NULL == (fp = fopen(filename, "rt+")))// 文件打开失败
{
printf("can't open %s !\n", filename);
return ;
}
else
{
length = CalSpaceNumCB(buf);
if( == length) //循环表数据已满
{
printf("CircleLink is full!\n");
return ;
}
else
{
while()
{
if( == length ) //循环表空间已满,还有部分数据未读入
{
printf("CircleBuf is full, some data still in file %s !\n", filename);
return -;
}
else
{
ch = fgetc(fp);
if(ch == EOF)
{
printf("file %s is over, data are in Circlebuf now!\n", filename);
//文件数据全部读完,并存入表中
return ;
}
else
{ InCircleBuf(buf, &ch, );
length--;
} } } }
}
return ;
}
环形buffer缓冲区的更多相关文章
- Java NIO Buffer缓冲区
原文链接:http://tutorials.jenkov.com/java-nio/buffers.html Java NIO Buffers用于和NIO Channel交互.正如你已经知道的,我们从 ...
- Nio再学习之NIO的buffer缓冲区
1. 缓冲区(Buffer): 介绍 我们知道在BIO(Block IO)中其是使用的流的形式进行读取,可以将数据直接写入或者将数据直接读取到Stream对象中,但是在NIO中所有的数据都是使用的换冲 ...
- Netty buffer缓冲区ByteBuf
Netty buffer缓冲区ByteBuf byte 作为网络传输的基本单位,因此数据在网络中进行传输时需要将数据转换成byte进行传输.netty提供了专门的缓冲区byte生成api ByteBu ...
- Java NIO 之 Buffer(缓冲区)
一 Buffer(缓冲区)介绍 Java NIO Buffers用于和NIO Channel交互. 我们从Channel中读取数据到buffers里,从Buffer把数据写入到Channels. Bu ...
- 笔记:Node.js 的 Buffer 缓冲区
笔记:Node.js 的 Buffer 缓冲区 node.js 6.0 之前创建的 Buffer 对象使用 new Buffer() 构造函数来创建对象实例,但权限很大,可以获得敏感信息,所以建议使用 ...
- NIO(一):Buffer缓冲区
一.NIO与IO: IO: 一般泛指进行input/output操作(读写操作),Java IO其核心是字符流(inputstream/outputstream)和字节流(reader/writer ...
- C++ buffer缓冲区的秘密
在搞数据库和C++进行连接的时候,遇到一个问题,就是如果前面用到了fflush(stdin)即清空缓冲区,就OK,如果不清空缓冲区就不能把记录加入到Mysql的数据库中, 但是即便如此,这个问题目前还 ...
- Node.js Buffer(缓冲区)
JavaScript 语言自身只有字符串数据类型,没有二进制数据类型. 但在处理像TCP流或文件流时,必须使用到二进制数据.因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门 ...
- node(3)Buffer缓冲区
buffer 专门用来存放二进制数据的缓冲区:处理文件流 TCP流 const buf = Buffer.from('runoob', 'ascii'); // 创建一个长度为 10.且用 0x1 填 ...
随机推荐
- STM8S——Analog/digital converter (ADC)
1.ADC1 and ADC2 are 10-bit successive approximation Anolog to Digital Converters. 所谓successive appro ...
- Netty源码分析第5章(ByteBuf)---->第4节: PooledByteBufAllocator简述
Netty源码分析第五章: ByteBuf 第四节: PooledByteBufAllocator简述 上一小节简单介绍了ByteBufAllocator以及其子类UnPooledByteBufAll ...
- [Hanani]高数相关知识记录
分部积分 \(\int uv'{\rm d}x=uv-\int u'v{\rm d}x\)
- 【深度学习的实用层面】(一)训练,验证,测试集(Train/Dev/Test sets)
在配置训练.验证.和测试数据集的过程中做出正确的决策会更好地创建高效的神经网络,所以需要对这三个名词有一个清晰的认识. 训练集:用来训练模型 验证集:用于调整模型的超参数,验证不同算法,检验哪种算法更 ...
- Bootstrap学习--栅格系统
响应式布局页面:即同一套页面可以兼容不同分辨率的设备. Bootstrap依赖于栅格系统实现响应式布局,将一行均分为12个格子,可以指定元素占几个格子. 实现过程 1.定义容器,相当于之前的table ...
- Appengine直接下载文件并保存到google drive
一直对下载文件比较感兴趣.前些日子无意搜到google 推出一项服务,可以直接将文件下载到google drive中,原型猛戳这里,但有限额限制.一时脑洞大开,可不可以在appengine 上架设服务 ...
- tree命令详解
基础命令学习目录首页 原文链接:http://man.linuxde.net/tree -a:显示所有文件和目录:-A:使用ASNI绘图字符显示树状图而非以ASCII字符组合:-C:在文件和目录清单加 ...
- 第14讲:嵌入式SQL语言(基本技巧)
一.交互式SQL的局限 & 嵌入式SQL的必要性 专业人员(如DBA)可以熟练地运用交互式SQL语言,但普通用户却不是那么容易上手,所以需要通过数据库应用程序来使用数据库.编写一个可以与数据库 ...
- 感谢Thunder团队
不知不觉中,团队开发的beta版本都已经结束.开发的路上我们一起解决了很多难题,相互帮助走到了现在. 首先我想感谢组长王航.认真负责合理分配任务,使得我们每次发布都可以顺利并且按时完成.感谢胡佑蓉,李 ...
- 使用sql查询mysql/oracle/sql server/gp数据库中指定表的字段信息(字段名/字段类型/字段长度/是否是主键/是否为空)
1,根据数据库类型拼接不同URL /** * 根据类型不同拼接连接的URL * @param dbType 1:mysql.2:oracle.3:sql server.4:gp * @param ip ...