提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录- 要求
- 一、环形缓冲区
- 二、环形缓冲区实现(C语言)
- 1. ringBuf.h
- 2. ringBufInit.c
- 3. ringBufRead.c
- 4. ringBufWrite.c
- 5. ringBufDataLen.c
- 6. ringBufFree.c
- 7. cmdHand.c
- 8. main.c
- 9. Makefile
要求
完成环形缓冲区函数库封装,生成成静态库和动态库,编写测试程序验证库文件,编写makefile实现编译,要求实现函数:
a、缓冲区初始化
b、往缓冲区写数据;
c、从缓冲区读数据;
d、计算缓冲区数据长度;
e、销毁缓冲区;
需要考虑到多个用户同时读写的情况,用到锁机制(互斥量)。
一、环形缓冲区关于什么是环形缓冲区,这里就不介绍了,网上大量文章都会介绍,读几篇基本就了解了。
参考:
C语言实现环形缓冲区
环形缓冲区ring_buffer的c语言实现
【数据结构及算法】环形缓冲区(ring buffer)实现原理及代码实现(C语言)
不罗嗦,直接上代码。
二、环形缓冲区实现(C语言) 1. ringBuf.h#ifndef _RINGBUF_H #define _RINGBUF_H #define read 0 #define write 1 #define quit 2 #define length 3 #include2. ringBufInit.c#include #include struct ringBuf { char *buffer; int size; int pRead; int pWrite; }; struct ringBuf *ringBufInit(struct ringBuf *ringBuffer,int size); int ringBufRead(struct ringBuf *ringBuffer,char *readBuf,int readLength); int ringBufWrite(struct ringBuf *ringBuffer,char *writeBuf,int writeLength); int ringBufDataLen(struct ringBuf *ringBuffer); void ringBufFree(struct ringBuf *ringBuffer); int cmdHand(char *cmd); #endif
#include "ringBuf.h" #include3. ringBufRead.cstruct ringBuf *ringBufInit(struct ringBuf* ringBuffer,int size) { ringBuffer = (struct ringBuf*)malloc(sizeof(struct ringBuf)); if(NULL == ringBuffer) { printf("ringBuffer malloc error!n"); exit(-1); } memset(ringBuffer,0,sizeof(struct ringBuf)); ringBuffer->buffer = (char*)malloc(size); memset(ringBuffer->buffer,0,size); ringBuffer->size = size; ringBuffer->pRead = 0; ringBuffer->pWrite = 0; return ringBuffer; }
#include "ringBuf.h"
int ringBufRead(struct ringBuf *ringBuffer,char *readBuf,int readLength)
{
int pre = 0; //记录read指针到缓冲区尾端数据长度
int last = 0; //记录剩余数据长度,也就是缓冲区头部的部分数据
if(NULL == ringBuffer)
{
printf("ringBuffer is NULL,ringBuffer init error!n");
exit(-1);
}
if(NULL == readBuf)
{
printf("readBuf is NULL,readBuf init error!n");
exit(-1);
}
if(readLength > ringBuffer->size)
{
printf("readLength is too long!n");
exit(-1);
}
if(readLength+ringBuffer->pRead <= ringBuffer->size)
{
memcpy(readBuf,ringBuffer->buffer+ringBuffer->pRead,readLength);
}else
{
int pre = ringBuffer->size - ringBuffer->pRead;
int last = readLength - pre;
memcpy(readBuf,ringBuffer->buffer+ringBuffer->pRead,pre);
memcpy(readBuf+pre,ringBuffer->buffer,last);
}
ringBuffer->pRead = (ringBuffer->pRead + readLength) % (ringBuffer->size);
return readLength; //后续要返回读有效数据长度
}
4. ringBufWrite.c
#include "ringBuf.h"
int ringBufWrite(struct ringBuf *ringBuffer,char *writeBuf,int writeLength)
{
int pre = 0; //记录write指针到缓冲区尾端长度
int last = 0; //记录剩余所需空间,也就是要往缓冲区头部写的部分空间
if(NULL == ringBuffer)
{
printf("ringBuffer is NULL,ringBuffer init error!n");
exit(-1);
}
if(NULL == writeBuf)
{
printf("writeBuf is NULL,writeBuf init error!n");
exit(-1);
}
if(writeLength > ringBuffer->size)
{
printf("writeLength is too long!n");
exit(-1);
}
if(writeLength+ringBuffer->pWrite <= ringBuffer->size)
{
memcpy(ringBuffer->buffer+ringBuffer->pWrite,writeBuf,writeLength);
}else
{
int pre = ringBuffer->size - ringBuffer->pWrite;
int last = writeLength - pre;
memcpy(ringBuffer->buffer+ringBuffer->pWrite,writeBuf,pre);
memcpy(ringBuffer->buffer,writeBuf+pre,last);
}
ringBuffer->pWrite = (ringBuffer->pWrite + writeLength) % (ringBuffer->size);
return writeLength; //后续要返回写有效数据长度
}
5. ringBufDataLen.c
#include "ringBuf.h"
int ringBufDataLen(struct ringBuf *ringBuffer)
{
int dataLen = 0;
if(NULL == ringBuffer)
{
printf("ringBuffer is NULL!n");
exit(-1);
}
if(ringBuffer->pWrite >= ringBuffer->pRead)
{
return (ringBuffer->pWrite - ringBuffer->pRead);
}else
{
return (ringBuffer->size - ringBuffer->pRead + ringBuffer->pWrite);
}
}
6. ringBufFree.c
#include "ringBuf.h"
void ringBufFree(struct ringBuf *ringBuffer)
{
if(NULL == ringBuffer)
{
printf("ringBuffer is NULL!n");
exit(-1);
}
if(ringBuffer->buffer != NULL)
{
free(ringBuffer->buffer);
ringBuffer->buffer =NULL;
}
free(ringBuffer);
ringBuffer = NULL;
}
7. cmdHand.c
#include "ringBuf.h"
int cmdHand(char *cmd)
{
if(NULL == cmd)
{
printf("cmd is NULL!n");
exit(-1);
}
if(strcmp("read",cmd) == 0)
{
return 0;
}
if(strcmp("write",cmd) == 0)
{
return 1;
}
if(strcmp("quit",cmd) == 0)
{
return 2;
}
if(strcmp("length",cmd) == 0)
{
return 3;
}
return 4;
}
8. main.c
#include "ringBuf.h"
int main()
{
int bufLen = 16; //缓冲区大小
char *cmd = NULL;
int cmdNum = 0;
int strNum = 0; //要读取的字符数
int dataLen = 0; //缓冲区有效数据长度
char readBuf[24] = {0}; //读缓存
char writeBuf[24] = {0}; //写缓存
cmd = (char *)malloc(12);
memset(cmd,0,12);
struct ringBuf *ringBuffer = NULL;
ringBuffer = (struct ringBuf*)malloc(sizeof(struct ringBuf));
ringBuffer = ringBufInit(ringBuffer,bufLen);
while(1)
{
printf("请输入指令(不要超过12字符):");
scanf("%s",cmd);
// printf("%sn",cmd);
//
cmdNum = cmdHand(cmd);
switch(cmdNum)
{
case read:
printf("请输入需要读取的字符数:");
scanf("%d",&strNum);
memset(readBuf,0,sizeof(readBuf));
ringBufRead(ringBuffer,readBuf,strNum);
printf("读取结果:%sn",readBuf);
break;
case write:
memset(writeBuf,0,sizeof(writeBuf));
printf("请输入要写入内容:");
scanf("%s",writeBuf);
ringBufWrite(ringBuffer,writeBuf,strlen(writeBuf));
printf("%s已写入n",writeBuf);
break;
case quit:
ringBufFree(ringBuffer);
printf("环形缓冲区已销毁!n");
exit(0);
break;
case length:
dataLen = ringBufDataLen(ringBuffer);
printf("缓冲区的有效数据长度为:%dn",dataLen);
break;
default:
printf("错误命令!n");
break;
}
}
return 0;
}
9. Makefile
#main: main.c libringBufInit.a libringBufWrite.a libringBufRead.a libringBufDataLen.a libringBufFree.a libcmdHand.a # gcc -o main main.c -L . -lringBufInit -lringBufWrite -lringBufRead -lringBufDataLen -lringBufFree -lcmdHand #libringBufInit.a: # gcc -c ringBufInit.c -o ringBufInit.o # ar rcs libringBufInit.a ringBufInit.o #libringBufWrite.a: # gcc -c ringBufWrite.c -o ringBufWrite.o # ar rcs libringBufWrite.a ringBufWrite.o #libringBufRead.a: # gcc -c ringBufRead.c -o ringBufRead.o # ar rcs libringBufRead.a ringBufRead.o #libringBufDataLen.a: # gcc -c ringBufDataLen.c -o ringBufDataLen.o # ar rcs libringBufDataLen.a ringBufDataLen.o #libringBufFree.a: # gcc -c ringBufFree.c -o ringBufFree.o # ar rcs libringBufFree.a ringBufFree.o # #libcmdHand.a: # gcc -c cmdHand.c -o cmdHand.o # ar rcs libcmdHand.a cmdHand.o #clean: # rm *.o # rm main # rm *.a main: main.c libringBufInit.so libringBufWrite.so libringBufRead.so libringBufDataLen.so libringBufFree.so libcmdHand.so gcc -o main main.c -L . -lringBufInit -lringBufWrite -lringBufRead -lringBufDataLen -lringBufFree -lcmdHand libringBufInit.so: gcc -fPIC -shared ringBufInit.c -o libringBufInit.so libringBufWrite.so: gcc -fPIC -shared ringBufWrite.c -o libringBufWrite.so libringBufRead.so: gcc -fPIC -shared ringBufRead.c -o libringBufRead.so libringBufDataLen.so: gcc -fPIC -shared ringBufDataLen.c -o libringBufDataLen.so libringBufFree.so: gcc -fPIC -shared ringBufFree.c -o libringBufFree.so libcmdHand.so: gcc -fPIC -shared cmdHand.c -o libcmdHand.so clean: rm main rm *.so



