#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. Mweb发布博客

    1.设置 + 选择红色 2     输入该输入的帐号和密码  博客网址就是你的博客文章页的地址,然后输入帐号和密码 3 API 地址在 设置-->博客设置,红色标记就是API地址 4 发布, ...

  2. Git工具使用小结

    昨天开始看一套java接口自动化的视频,今天看到的一章是关于git这个工具使用的,上大学那会用过svn作为版本管理工具,包括现在所在的公司,用的也还是svn进行管理.其实老早就听闻过Git,Githu ...

  3. 【LeetCode算法题库】Day4:Regular Expression Matching & Container With Most Water & Integer to Roman

    [Q10] Given an input string (s) and a pattern (p), implement regular expression matching with suppor ...

  4. mac zsh不自动加载~/.bashrc

    修改了bashrc, 新开一个终端都要source一下才起作用. 网上有说需要在 . bash_profile加载一次.bashrc. 但是这个和我的问题不一样. 我用的是zsh,需要修改~/.zsh ...

  5. etcd集群证书安装过程一

    为确保安全,kubernetes 系统各组件需要使用 x509 证书对通信进行加密和认证. CA (Certificate Authority) 是自签名的根证书,用来签名后续创建的其它证书. 本文档 ...

  6. UVA 816 Abbott's Revenge 紫书

    紫书的这道题, 作者说是很重要. 但看着题解好长, 加上那段时间有别的事, 磨了几天没有动手. 最后,这道题我打了五遍以上 ,有两次被BUG卡了,找了很久才找到. 思路紫书上有,就缺少输入和边界判断两 ...

  7. ubuntu下import matplotlib错误解决办法

    环境:ubuntu16.04,python2.7,tensorflow1.4.0 问题: ImportError: No moudule named _tkinter, please install ...

  8. 拒绝滥用golang defer机制

    原文链接 : http://www.bugclosed.com/post/17 defer机制 go语言中的defer提供了在函数返回前执行操作的机制,在需要资源回收的场景非常方便易用(比如文件关闭, ...

  9. json转对象

    1,引入依赖 <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib& ...

  10. 第二阶段Sprint冲刺会议9

    进展:查看有关“共享平台”的资料,看如何实现上传下载功能,并尝试编码,没有成功.