#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#define SIZE 66 //明示常量定义66,可以自行修改
//#define SIZE1 SIZE-1 //保证menu的返回的数组不会溢出
void eatline(void);
void answer_judge(char ch[]);
//void* s_gets(char* st, int n);
typedef int datatype;
//设计结构体,定义用户相关信息
typedef struct client
{
datatype id; //用户id序号
char name[SIZE]; /*定义字符数组存储用户名字,可考虑用字符指针,
但是字符指针不能逐个打印字符,暂且先用字符数组*/
/*struct client* next;*/
}dclient, * nclient;
//设计队列节点类型(即节点的内容)
typedef struct node
{
dclient data; //队列节点的数据域具有dclient类型
struct node*next; //队列节点的next指针域
}ND, * PND;
//设计队列基本操作的指针,管理结构体
typedef struct linkqueue
{
PND front; //队头指针
PND rear; //队尾指针
}LQ, * PLQ;
//构造函数,用于建立链式队列
PLQ initqueue(void)
{
//分配管理结构体内存空间
PLQ queue = (PLQ)malloc(sizeof(LQ)); /*定义plq类型的队列,一定要进行 初始化 申请大小为队列操作本身lq的空间
因为系统不会自动为指针申请一个可以使用的内存空间,为他提供存放结构体变量*/
if (queue == NULL) //判断代码健壮性是否良好
return NULL;
PND phead = (PND)malloc(sizeof(ND));//定义一个PND类型的头指针,进行 初始化 申请大小为队列节点ND的空间
if (phead == NULL)
{
printf("the phread malloc fail\n");
free(queue); //因为phread申请失败,所以管理结构体queue也没有作用了。
return NULL;
}
queue->front = phead;//队列 头尾指针 指向头结点
queue->rear = phead;
phead->next = NULL; //头节点的next指向空
return queue; //将*plq类型的queue返回
//also you can do
//queue->front = (PND)malloc(sizeof(ND));
//if (queue->front == NULL)
//{
// printf("malloc fail\n");
// free(queue);
// return NULL;
//}
//queue->rear = queue->front;
//queue->front->next = NULL;
//return queue;
}
bool enqueue(PLQ queue)
{
static datatype tid = 0; /*定义静态整型变量总派发tid,刚开始id空为0
static具有静态存储期, 文件作用域
块作用域中的静态变量贯穿整个程序的生命周期*/
PND pnew = (PND)malloc(sizeof(ND)); //定义一个node类型新节点用于存放新用户信息
if (pnew == NULL) //判断代码健壮性好坏
return false;
pnew->next = NULL; //pnew的next指向空
//memset(pnew->data.name, 0, SIZE); //memset()初始化函数,将pnew的name 的 SIZE范围 全部变成 0
//该函数在string.h库里
printf("please enter the client name: ");
gets(pnew->data.name); /*atttion: 表达data的name,需要用.结构成员运算符。否则
出现E3364错误, 结构体变量是用"."*/
//eatline();
tid++; //输入用户名字成功,总id递增
pnew->data.id = tid; //插入用户名后,用户获得一个id,id+1
queue->rear->next = pnew; //将rear的next指向新节点,完成节点的连接
queue->rear = pnew; //将rear的位置移到最新节点位置,保证始终为队尾
return true;
}
bool is_empty(PLQ queue)
{
if ((queue->front == queue->rear)||(queue->front->next==NULL)) //如果队头就是队尾,则队列为空
return true;
else
return false;
}
dclient dequeue(PLQ queue,dclient vall) //形参为queue管理结构体,以及dclient结构体变量val
{
if (is_empty(queue))
{
printf("the linkqueue is empty\n");
return;
}
PND ptamp = queue->front->next;
vall = ptamp->data; //将即将出队的用户名字存入指针
queue->front->next = ptamp->next;
printf("id: %d,name: %s is handing business\n", ptamp->data.id, ptamp->data.name);
if (queue->front->next == NULL)
queue->rear = queue->front;
free(ptamp);
return vall;
//return true;
}
bool showqueue(PLQ queue)
{
//datatype id = 0; //定义用户id,并赋值为0
if (is_empty(queue))
{
printf("the linkqueue is empty\n");
return false;
}
PND ptamp = queue->front->next;
printf("******* queue *******\n");
printf("id\tname\n");
while (ptamp != NULL)
{
//id++;
//ptamp->data.id = id; //每遍历到一个节点,就派发给用户一个id
printf("%d\t", ptamp->data.id);
printf("%s\t", ptamp->data.name);
ptamp = ptamp->next; //依次向后遍历
printf("\n");
}
return true;
}
bool clearqueue(PLQ queue) //下班,销毁队列节点,只剩头节点
{
queue->rear = queue->front; //将队尾指针指向队头指针,归位到头节点phead
PND ptamp = queue->front->next; //定义一个指向队列的临时指针,将临时指针指向首节点,方便后续节点删除操作
while (ptamp != NULL) //ptamp只要不等于NULL,就证明队列内依然有节点,执行删除操作
{
queue->front->next = ptamp->next; //参照出队操作,将front指向下一个节点
free(ptamp); //将ptamp删除
ptamp = queue->front->next; //将ptamp节点再次指向新首节点
}
queue->front->next = NULL; //队列没有节点后,头节点指向空.
return true;
}
//处理fgets()函数存储'\n',的办法,这个办法封装一个函数
//char* s_gets(char* st_name, int size)/*返回char型指针,字符型指针st, 形参整型变量n
// st存入实参的数组,n存入实参的数组最大数量*/
//{
// char *ret_name; //定义一个字符指针ret_name
// int i = 0; //整型i=0用于循环
// ret_name = fgets(st_name, size, stdin);//从stdin标准输入中输入,读入size大小,放进st_name。
// if (ret_name != NULL)
// {
// while (st_name[i] != '\n' && st_name[i] != '\0') //遍历,直到st_name的结尾
// i++;
// if (st_name[i] == '\n') //遇到\n将\n替换成\0
// st_name[i] = '\0';
// else
// while (getchar() != '\n') //遇到\0则将输入行多出来的字符(\0后面的字符)删去
// continue;
// }
// return ret_name;
//}
//检查用户输入是否正确
void answer_judge(char ch[SIZE])
{
while (strcmp(ch, "1") != 0 && strcmp(ch, "2") != 0 && strcmp(ch, "3") != 0
&& strcmp(ch, "4") != 0 && strcmp(ch, "5") != 0 && strcmp(ch, "6") != 0)
{
printf("please enter 1,2,3,4,5 or 6: ");
//eatline();
gets(ch);
}
return;
}
char menu(void)//菜单函数显示菜单
{
char ch[SIZE]={0};//定义符号数组,用于存储用户输入的数据
printf("******************** bank **************************\n");
printf("please enter your choice(q to quit): \n");
printf("1) call and queue 2) handle the business\n");
printf("3) display the queue 4) knock off the work\n");
printf("5) claer the screen 6) quit\n");
printf("****************************************************\n");
//scanf_s("%s", ch,66);
gets(ch); //使用gets()可以存储空格
answer_judge(ch);
return ch[0]; //返回数组的首元素,其他元素也用不上嘛,在answer_judeg里被删除了
}
void eatline(void)
{
while (getchar()!= '\n') //清除剩余字符
continue; //持续从行缓冲区提取字符,直到遇到'\n'结束循环
return;
}
//void other_clearqueue(plq queue)
int main(void)
{
char ch; //定义符号变量ch
struct client* vall=(struct client*)malloc(sizeof(struct client));//初始化nclient结构体指针val并申请空间类型大小为dclient的空间
if (vall == NULL)
return NULL;
//datatype tid = 0; //定义整型指针item,以及总上班内总共派发的totle_id.totle_id赋值为0
PLQ queue=initqueue(); //定义plq结构体指针
while ((ch=menu()) != '6')
{
switch (ch)
{
case '1':enqueue(queue); break;
case '2':dequeue(queue,*vall); break; //解引用val指针,变成结构体,将它作为实参传入dequeue
case '3':showqueue(queue); break;
case '4':
{
clearqueue(queue);
printf("clear sucess\n");
break;
}
case '5':system("cls"); break;
}
}
printf("Done!");
printf("the dequeue vall is:%d %s", vall->id, vall->name);
return 0;
}
我想问一下为什么最后我打印vall结构体的数据时,是乱码的,看了一下dequeue返回的值,在main函数并没有找到,怎么解决呀