环形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 填 ...
随机推荐
- UWP 五星评价(不跳转到龟速商店)
之前写过一篇文章 UWP 五星好评 代码如下 var pfn = Package.Current.Id.FamilyName; await Launcher.LaunchUriAsync(new ...
- C# string 的一点属性、方法什么的
今天学的基本可以说是都属于方法和属性 下面这两句话非常重要,确实非常重要 凡是可以 “ . ” 出来的,前面是黑色的小扳手的:属性 紫色的立方体的:方法 这个对于以后自学帮助是不小的,当然, ...
- zabbix4.0LTS安装配置
一.环境准备 1.最小化安装centos7.5系统 2.安装常用软件包 yum install -y net-tools vim bash-completion 3.关闭selinux和修改主机名 v ...
- [MIT Intro. to algo]Lecture 1: 课程介绍,算法优势,插入算法和归并算法分析,渐近符号
The theoretical study of computer program performance and resource useage. First, analysis and the ...
- [Unity] unity5.3 assetbundle打包及加载
Unity5.3更新了assetbundle的打包和加载api,下面简单介绍使用方法及示例代码. 在Unity中选中一个prefab查看Inspector窗口,有两个位置可以进行assetbundle ...
- CF 675E Trains and Statistic
草稿和一些题解而已 因为指针太恶心了 所以query决定还是要试试自己yy一下 #include<cstdio> #include<cstring> #include<i ...
- 正则表达式的捕获组(Java)
捕获组分类 普通捕获组(Expression) 命名捕获组(?<name>Expression) 普通捕获组 从正则表达式左侧开始,每出现一个左括号“(”记做一个分组,分组编号从1开始.0 ...
- 如何在window服务器上搭建一个能代替ftp的传输工具
通常对于服务器上的文件管理和数据传输都是利用ftp来实现,但随着存储技术的发展,数据资产的存储规模和复杂程度不断提高,传统的ftp传输显得有笨重.今天给大家介绍一款能够取代ftp的在线文档管理软件—— ...
- 【CentOS 7】scp示例
1,从远端拷贝到本地 /tmp路径 root@raspberrypi:/download/api_weather# scp root@123.207.xxx.xxx:/xxx/* /tmp 2,从本地 ...
- python3使用csv包,读写csv文件
python操作csv,现在很多都用pandas包了,不过python还是有一个原始的包可以直接操作csv,或者excel的,下面举个例子说明csv读写csv文件的方法: import os impo ...