#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缓冲区的更多相关文章

  1. Java NIO Buffer缓冲区

    原文链接:http://tutorials.jenkov.com/java-nio/buffers.html Java NIO Buffers用于和NIO Channel交互.正如你已经知道的,我们从 ...

  2. Nio再学习之NIO的buffer缓冲区

    1. 缓冲区(Buffer): 介绍 我们知道在BIO(Block IO)中其是使用的流的形式进行读取,可以将数据直接写入或者将数据直接读取到Stream对象中,但是在NIO中所有的数据都是使用的换冲 ...

  3. Netty buffer缓冲区ByteBuf

    Netty buffer缓冲区ByteBuf byte 作为网络传输的基本单位,因此数据在网络中进行传输时需要将数据转换成byte进行传输.netty提供了专门的缓冲区byte生成api ByteBu ...

  4. Java NIO 之 Buffer(缓冲区)

    一 Buffer(缓冲区)介绍 Java NIO Buffers用于和NIO Channel交互. 我们从Channel中读取数据到buffers里,从Buffer把数据写入到Channels. Bu ...

  5. 笔记:Node.js 的 Buffer 缓冲区

    笔记:Node.js 的 Buffer 缓冲区 node.js 6.0 之前创建的 Buffer 对象使用 new Buffer() 构造函数来创建对象实例,但权限很大,可以获得敏感信息,所以建议使用 ...

  6. NIO(一):Buffer缓冲区

    一.NIO与IO: IO:  一般泛指进行input/output操作(读写操作),Java IO其核心是字符流(inputstream/outputstream)和字节流(reader/writer ...

  7. C++ buffer缓冲区的秘密

    在搞数据库和C++进行连接的时候,遇到一个问题,就是如果前面用到了fflush(stdin)即清空缓冲区,就OK,如果不清空缓冲区就不能把记录加入到Mysql的数据库中, 但是即便如此,这个问题目前还 ...

  8. Node.js Buffer(缓冲区)

    JavaScript 语言自身只有字符串数据类型,没有二进制数据类型. 但在处理像TCP流或文件流时,必须使用到二进制数据.因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门 ...

  9. node(3)Buffer缓冲区

    buffer 专门用来存放二进制数据的缓冲区:处理文件流 TCP流 const buf = Buffer.from('runoob', 'ascii'); // 创建一个长度为 10.且用 0x1 填 ...

随机推荐

  1. this四种绑定方式之间的奇淫技巧

    写在前面 上一篇中,我们对于JavaScript中原始值.复杂值以及内存空间进行了一个深入浅出的总结,这次我们来聊一聊JavaScript中this关键字的深入浅出的用法. 在 JavaScript ...

  2. Form,tagName和nodeName的区别

    首先介绍DOM里常见的三种节点类型(总共有12种,如docment):元素节点,属性节点以及文本节点,例如<h2 class="title">head</h2&g ...

  3. Session里存的密码或其他信息如何获取。

    1.首先找到登陆界面,看给session里存的是什么,是以什么格式去存的(个人这边是commonAction): 2.其次在需要的界面进行获取,拿出想要的密码或其余值.(密码可能是加密过的,如想做密码 ...

  4. Macaca环境搭建全教程

    首先想要会Macaca,还得先会用github,不然你得死……因为各种例子都在git上,官网也一样,蛋疼的很…… #基础环境 1.JDK:jdk1.8-配置变量 2.Android SDK:sdk   ...

  5. 在Telnet中用FTP传输文件

    如果用 Telnet 传输文件? 在自己的机子上架设FTP服务器,然后登陆远程机后,就可以登录自己的FTP.利用PUT(上传命令),就可以把远程电脑的文件下载下来.     如果出现连接不上FTP,也 ...

  6. Linu之linux系统基础优化和基本命令

    Linux系统基础优化和基本命令 网络参数设定命令 ifconfig: 查询,设置网卡和ip等参数 ifup,ifdown: 脚本命令,更简单的方式 ip: 符合指令,直接修改上述功能 编辑网卡配置文 ...

  7. mysql查询当天,前一天,一周,一个月

    当天 select * from 表名 where to_days(时间字段名) = to_days(now()); 昨天 SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ...

  8. netty+proto使用简要记录

    1. maven环境配置protobuf 2.生成.proto文件 3.将.proto转为java文件 打开电脑的cmd,进入.proto所在文件位置,输入命令:protoc.exe --java_o ...

  9. JavaWeb项目学习教程(2) 系统数据库设计

    最开始本来想写一个管理系统,因为考虑到期末来临,我女朋友就可以看着教程然后学一些东西,然后可以自己慢慢手敲代码.但无奈自己也太懒,两个月过后,我才开始继续写这个博客,而现在我都已经开学了.不过博客还是 ...

  10. 1、AutoCAD ObjectARX开发版本对照表

    ObjectARX开发版本对照表 序号 CAD版本 版本号 二进制兼容 .net框架 ObjectARX开发环境 VC版本号 MAC OS平台 WINDOWS平台 VC版本 _MSC_VER 1 R1 ...