#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 ;
}
05-22 20:58