需求描述:實現一個固定長度的字符緩存管理結構,實現字符串的寫入和讀出。
1)隊列加數據,向cb尾追加長爲length的字符串,存在putting中; 當緩衝剩餘空間remain<length時,追加長爲remain的字符串,函數返回實際有效存放到緩衝中的字符串;
2)隊列取數據,在cb中讀取長度爲length的字符串,存於getting中;當隊列存放的字符數used<length時,只讀取長爲used的字符串,讀取字符串後,隊列中相應緩衝不再使用。
特別聲明,本文源碼在VC6.0上測試通過。
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
// 定義隊列緩衝長度,實際長度爲SIZE-1
#define SIZE 10
// 定義數組循環隊列
typedef struct cb_s
{
char *queue;
unsigned long front;
unsigned long rear;
}cb_t;
void cbInit(cb_t **cb, unsigned long size); // 隊列初始化函數
unsigned long cbPuts(cb_t *cb, char *putting, unsigned long length); // 隊列加數據函數
char *cbGets(cb_t *cb, unsigned long length, char *getting); // 隊列取數據函數
void cbDestroy(cb_t *cb); // 隊列釋放函數
void main(void)
{
cb_t *pcb = NULL;
char *putting = "a+b#c*d-e!f&g";
char getting[SIZE] = {0};
cbInit(&pcb, SIZE);
printf("Test of [cbPuts] operation>>\n");
printf("%d\n\n", cbPuts(pcb, putting, 12));
printf("Test of [cbGets] operation>>\n");
printf("%s\n\n", cbGets(pcb, 5, getting));
printf("Test of [cbPuts] operation>>\n");
printf("%d\n\n", cbPuts(pcb, putting, 4));
printf("Test of [cbGets] operation>>\n");
printf("%s\n\n", cbGets(pcb, 5, getting));
printf("Test of [cbGets] operation>>\n");
printf("%s\n\n", cbGets(pcb, 5, getting));
cbDestroy(pcb);
}
/* 隊列初始化函數,cb爲隊列緩衝,size是緩衝大小 */
void cbInit(cb_t **cb, unsigned long size)
{
*cb = (cb_t *)malloc(sizeof(cb_t));
if ((NULL == *cb) || (NULL == cb))
{
printf("cbInit:Insufficient Memory!\n");
exit(0);
}
(*cb)->queue = (char *)malloc(size * sizeof(char));
if (NULL == (*cb)->queue)
{
printf("cbInit:Insufficient Memory!\n");
exit(0);
}
memset((*cb)->queue, 0, size * sizeof(char));
(*cb)->front = 0;
(*cb)->rear = 0;
}
/* 隊列加數據函數,向cb尾追加長爲length的字符串,存在putting中;
當緩衝剩餘空間remain<length時,追加長爲remain的字符串,函數返回實際有效存放到緩衝中的字符串 */
unsigned long cbPuts(cb_t *cb, char *putting, unsigned long length)
{
unsigned long index = 0;
if ((NULL == cb) || (NULL == putting))
{
printf("cbPuts:Insufficient Memory!\n");
exit(0);
}
if ((cb->rear +1) % SIZE == cb->front) // 隊列已滿
{
printf("Queue is full!\n");
return 0;
}
else // 隊列未滿
{
for (index = 0; index < length; index++)
{
if ((cb->rear + 1) % SIZE != cb->front) // 隊列未滿,逐字符入隊列
{
cb->rear = (cb->rear + 1) % SIZE;
*(cb->queue + cb->rear) = *(putting + index);
}
else
{
break; // 隊列剩餘空間<length,隊列滿時跳出循環;否則,跳過該語句
}
}
return index;
}
}
/* 隊列取數據函數,在cb中讀取長度爲length的字符串,存於getting中;
當隊列存放的字符數used<length時,只讀取長爲used的字符串,讀取字符串後,隊列中相應緩衝不再使用 */
char *cbGets(cb_t *cb, unsigned long length, char *getting)
{
unsigned long index = 0;
if (NULL == cb)
{
printf("cbGets:Insufficient Memory!\n");
exit(0);
}
if (cb->rear == cb->front) // 隊列爲空
{
printf("Queue is empty!\n");
return NULL;
}
else // 隊列非空
{
for (index = 0; index < length; index++)
{
if (cb->rear != cb->front) // 隊列非空,逐字符出隊列
{
cb->front = (cb->front + 1) % SIZE;
*(getting + index) = *(cb->queue + cb->front);
*(cb->queue + cb->front) = 0; // 出隊列緩存清零
}
else
{
break; // 隊列存放字節數<length,隊列空時跳出循環;否則,跳過該語句
}
}
*(getting + index) = '\0';
return getting;
}
}
/* 隊列釋放函數,釋放cb佔用的內存 */
void cbDestroy(cb_t *cb)
{
if (NULL == cb)
{
printf("cbDestroy:Insufficient Memory/Queue isnot Existing!\n");
exit(0);
}
free(cb->queue);
cb->queue = NULL;
free(cb);
}