C语言 数据结构 队列 字符数组环形队列 实现变长字符串在缓冲区读和(可覆盖式)写

/*--------------------------------------------------
实验环境:VC++6.0
--------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef unsigned char u8;
typedef unsigned int  u16;
typedef char s8;
typedef int  s16;
typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
typedef enum {false = 0,true = 1}bool;

#define MAXSTRLEN	30 //字符串环形队列申请空间为30个字符,但实际使用29个
typedef char ElemType;
typedef struct
{
    ElemType *queue; //指向存储队列的数组空间
	u8 front, rear;  //front:指向队首元素 rear:指向队尾元素的下一个空元素
	u8 len;          //当前队列中元素个数
	u8 MaxSize;      //数组空间可存储最多元素个数为 MaxSize-1
}Queue;

/*******************************************************
InitQueue():初始化队列
*******************************************************/
void InitQueue(Queue* Q)  //初始化队列
{
	(*Q).MaxSize =MAXSTRLEN;  //队列空间分配30个元素
	(*Q).queue = (ElemType *)calloc((*Q).MaxSize,sizeof(ElemType));
	Q->front=Q->rear=Q->len=0;		//初始队列为空
}

/*******************************************************
OutQueue():队首元素出队
*******************************************************/
ErrorStatus OutQueue(Queue* Q)  //删除队列元素(出队-删除队首元素)
{
	if(Q->front==Q->rear)		
		return  ERROR;		//队列为空,则返回错误
	Q->front = (Q->front+1)%Q->MaxSize;  //删除队首元素
	Q->len--;
	return SUCCESS;	
}

/*******************************************************
GetItem():获取字符串环形队列队首元素--即单个字符,同时队首元素出队
*******************************************************/
ErrorStatus GetItem(Queue* Q, ElemType* item)  //获取队首元素
{
	if(Q->front==Q->rear)		
		return  ERROR;		//队列为空,则返回错误
	*item =	Q->queue[Q->front];
	Q->front = (Q->front+1)%Q->MaxSize;  //删除队首元素
	Q->len--;
	return SUCCESS;	
}

/*******************************************************
EmptyQueue():队列查空
*******************************************************/
bool EmptyQueue(Queue* Q)  //检查队列是否为空,空返回 true,非空返回 false
{
	return Q->front==Q->rear;
}

/*******************************************************
InQueue():队列元素入队
*******************************************************/
void InQueue(Queue* Q, ElemType item)  //入队,队列满,则覆盖旧数据
{	    	
	//对存储空间是否用完进行处理
	if((Q->rear+1)%Q->MaxSize==Q->front)
	{
		OutQueue(Q); //队列满,则覆盖最老元素,即队首元素出队
		printf("write full\n");
	}
		
	//存储元素数据
	Q->queue[Q->rear] = item;
	//求出队尾的下一个将要存储数据的位置
	Q->rear = (Q->rear+1)%Q->MaxSize;
	Q->len++;
}

/*******************************************************
ClearQueue():清空队列队列
*******************************************************/
void ClearQueue(Queue* Q)  //清除队列,释放动态内存
{
	if(Q->queue!=NULL)
		free(Q->queue);
	Q->front=Q->rear=Q->len=0;		//初始队列为空
	Q->queue =NULL;
	Q->MaxSize = 0;
}

/*******************************************************
writestr: 向字符串环形队列写入指定长度的字符串
	Q:   字符数组环形队列
	instr:写入队列的字符串
	len:要写入字符缓存队列的字符长度
*******************************************************/
void writestr(Queue* Q, u8* instr, u16 len)
{
	u16 i=0;
	while(i<len)
	{ InQueue(Q,instr[i++]);}	
	//或者
	/*
	while(len--)
	{ InQueue(Q,*instr++);}
	*/
}

/*******************************************************
readstr: 从字符串环形队列中读取指定长度的字符串
	outstr:输出字符串
	len:想要读取字符串长度
	rlen:返回读取到字符串实际长度
*******************************************************/
void readstr(Queue* Q, u8* outstr, u16 len, u16* rlen)
{
	while(len--)
	{		
		if(ERROR==GetItem(Q,outstr))
		{
			printf("read over\n");
			break;
		}
		else
		{
			(*rlen)++;
			outstr++;
		}			
	}	
}

/*******************************************************
myprintf:输出字符数组内所有字符,包括'\0'
	str: 字符串
	len:字符串长度	
*******************************************************/
void myprintf(u8 *str, u16 len)
{
	u16 i=0;	
	while(len--)
	{
		printf("%c",str[i++]);
	}	
	printf("\n");
}

void main()
{
	Queue queStr;
	u8 temp[100];	
	u8 buff[100];	
	u16 rlen=0;
	
	InitQueue(&queStr);
	while(1)
	{
		printf("please input a string:\n");
		scanf("%s",temp);
		
		writestr(&queStr, temp,strlen((const char *)temp));
		
		printf("---queStr.queue:----------\n");
		myprintf(queStr.queue, MAXSTRLEN);		
		
		readstr(&queStr, buff, MAXSTRLEN, &rlen);
		printf("\n----read out len:%d------\n",rlen);
		myprintf(buff,rlen);		
		
		rlen =0;
		printf("\n\n");
	}		
	
}

/************控制台运行结果****************************
please input a string:
1234567890qwertyuiop[]\asdfghjk
write full
write full
---queStr.queue:----------
k234567890qwertyuiop[]\asdfghj
read over

----read out len:29------
34567890qwertyuiop[]\asdfghjk


please input a string:
asdfg
---queStr.queue:----------
kasdfg7890qwertyuiop[]\asdfghj
read over

----read out len:5------
asdfg


please input a string:
xcvbn
---queStr.queue:----------
kasdfgxcvbnwertyuiop[]\asdfghj
read over

----read out len:5------
xcvbn


please input a string:
1234567890-zxcvbhjsdfghjkertyuil;',.
write full
write full
write full
write full
write full
write full
write full
---queStr.queue:----------
dfghjkertyuil;',.7890-zxcvbhjs
read over

----read out len:29------
890-zxcvbhjsdfghjkertyuil;',.


please input a string:

*****************************************/

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值