开始学习队列ADT,这次弄个明晰的菜单出来。
1.问题(solved):使用switch选择执行,但读取添加、删除、全删除三个选项后就程序错误,也许是相关的三个函数有错误。
定义变量的时候错误,将变量定义成指针:
Student *temp_student=NULL;
Queue *man=NULL;
造成内存无法读取,换成:
Student temp_student={0};
Queue man={0};
程序已经可以运行。现在开始试着发现运行中的具体问题。
2.问题(solved):数据存储错误,最后一项会漏掉,进行删除等操作后甚至会报错。
显示函数:
void ShowQueue(Queue *pqueue)
{
Queue pscan=*pqueue;
fputs("*********DataBase*********\n",stdout);
if(!pscan.nodes)
fputs("No Data Found!\n",stdout);
else
{
printf("(%d)Data Found.\n",pscan.nodes);
while(pscan.front)//!!!原错为(pscan.front->next)
{
printf("NO.%d:Name:%s,Score:%hd.\n",
pscan.nodes,pscan.front->student.name,pscan.front->student.score);
pscan.front=pscan.front->next;
}
}
}
将原错while(pscan.front->next)改为while(pscan.front);
这个问题莫名其妙自己解决了。
3.问题(solved):显示函数的次序数有问题。总是显示最后一项。
后来终于发现:结构定义时,queue结构中的nodes计数标签存储的就是最后一项,因为queue并不是链表项,node才是链表项,所以如果要对每一项进行编码,必须在node结构里添加编码计数标签。
typedef struct student
{
char name[LEN_NAME];
short score;
}Student;
typedef struct node
{
Student student;
struct node *next;
}Node;
typedef struct queue
{
Node *front;
Node *rear;
int nodes;
}Queue;
4.问题(solved):全部删除函数的显示有错
short DeQueue(Student *pstudent,Queue *pqueue)
{
if(IsQueueEmpty(pqueue))
return 0;
Node *ptemp=pqueue->front;
*pstudent=ptemp->student;//错误原:pstudent=&(ptemp->student);
pqueue->front=pqueue->front->next;
free(ptemp);
pqueue->nodes--;
if(!(pqueue->nodes))
pqueue->rear=NULL;
return 1;}
void EmptyQueue(Student *pstudent,Queue *pqueue)
{
int i=pqueue->nodes;
while(DeQueue(pstudent,pqueue))
printf("Data->name:%s,score:%hd has cleaned.\n",
pstudent->name,pstudent->score);
printf("Over!%d data has cleaned.\n",i);
}
发现:错误原:pstudent=&(ptemp->student);这句代码有问题,改成:*pstudent=ptemp->student;就能顺利显示被删除数据的内容
个人理解:指向Student结构类型的指针pstudent指向ptemp->student的地址,但是ptemp内存被free(ptemp)清理,造成指向错误。
CPrimerPlusV6-17.4(队列ADT)-自改代码
/*声明接口*/
/*声明接口*/
#define _CRT_SECURE_NO_WARNINGS
#ifndef QUEUE_H
#define QUEUE_H
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define MAX_QUEUE 10
#define LEN_NAME 20
#define MAX_SCORE 100
typedef struct student
{
char name[LEN_NAME];
short score;
}Student;
typedef struct node
{
Student student;
struct node *next;
}Node;
typedef struct queue
{
Node *front;
Node *rear;
int nodes;
}Queue;
void exit_normal(void);
void exit_abnormal(void);
char *s_gets(char *p,int n);
void InitializeQueue(Queue *pqueue);
short IsQueueFull(const Queue *pqueue);
short IsQueueEmpty(const Queue *pqueue);
void SearchQueue(const Student *pstudent,const Queue *pqueue);
short EnQueue(Student *pstudent,Queue *pqueue);
short DeQueue(Student *pstudent,Queue *pqueue);
void EmptyQueue(Student *pstudent,Queue *pqueue);
void ShowQueue(const Queue *pqueue);
#endif
/*定义接口*/
/*定义接口*/
#include"queue.h"
void exit_normal(void)
{
fputs("ProgramOver!!!\n",stdout);
}
void exit_abnormal(void)
{
fputs("ErrorHappened!Over!\n",stdout);
}
char *s_gets(char *p,int n)
{
char *gets,*find;
if(*(gets=fgets(p,n,stdin))!=10&&gets)
{
if(find=strchr(p,10))
*find=0;
else
while(getchar()!=10);
}
else
return 0;
return gets;}
void InitializeQueue(Queue *pqueue)
{
pqueue->front=NULL;
pqueue->rear=NULL;
pqueue->nodes=0;
}
short IsQueueFull(const Queue *pqueue)
{
return((pqueue->nodes==MAX_QUEUE)?1:0);
}
short IsQueueEmpty(const Queue *pqueue)
{
return(!(pqueue->nodes)?1:0);
}
void SearchQueue(const Student *pstudent,const Queue *pqueue)
{
int i=0;
Node *pscan=pqueue->front;
while(pscan)
{
if(!strcmp(pstudent->name,pscan->student.name))
{
printf("count:%d,name:%s,score:%hd\n",i+1,pscan->student.name,pscan->student.score);
i++;
}
pscan=pscan->next;
}
if(!i)
fputs("No Data Found!\n",stdout);
}
short EnQueue(Student *pstudent,Queue *pqueue)
{
Node *pnew;
if(IsQueueFull(pqueue))
return 0;
if(!(pnew=(Node *)calloc(1,sizeof(Node))))
{
fputs("No Memory Available!",stderr);
return 0;
}
pnew->student=*pstudent;
pnew->next=NULL;
if(IsQueueEmpty(pqueue))
pqueue->front=pnew;
else
pqueue->rear->next=pnew;
pqueue->rear=pnew;
pqueue->nodes++;
return 1;}
short DeQueue(Student *pstudent,Queue *pqueue)
{
if(IsQueueEmpty(pqueue))
return 0;
Node *ptemp=pqueue->front;
*pstudent=ptemp->student;
pqueue->front=pqueue->front->next;
free(ptemp);
pqueue->nodes--;
if(!(pqueue->nodes))
pqueue->rear=NULL;
return 1;}
void EmptyQueue(Student *pstudent,Queue *pqueue)
{
int i=pqueue->nodes;
while(DeQueue(pstudent,pqueue))
printf("Data->name:%s,score:%hd has cleaned.\n",pstudent->name,pstudent->score);
printf("Over!%d data has cleaned.\n",i);
}
void ShowQueue(const Queue *pqueue)
{
Queue pscan=*pqueue;
fputs("*********DataBase*********\n",stdout);
if(!pscan.nodes)
fputs("No Data Found!\n",stdout);
else
{
printf("(%d)Data Found.\n",pscan.nodes);
for(int i=1;pscan.front;i++)
{
printf("NO.%d:Name:%s,Score:%hd.\n",i,pscan.front->student.name,pscan.front->student.score);
pscan.front=pscan.front->next;
}
}
}
/*使用接口*/
/*使用接口*/
#include"queue.h"
int showmenu(void);
short executemenu(int choice,Student *pstudent,Queue *pqueue);
int main()
{
Student temp_student={0};
Queue man={0};
atexit(exit_normal);
InitializeQueue(&man);
while(executemenu(showmenu(),&temp_student,&man));
EmptyQueue(&temp_student,&man);
return 0;}
//
int showmenu(void)
{
const char *pch=0;
int choice=0;
const char *menu="EFDCSQ";
fputs("***************Menu***************\n",stdout);
fputs("E)AddData F)Search Data\n",stdout);
fputs("D)Delete a Data C)Delete all Data\n",stdout);
fputs("S)Show all Data Q)QuitProgram\n",stdout);
for(fputs("Your Choice:",stdout),choice=fgetc(stdin);
!strchr(menu,toupper(choice));
fputs("Your Choice:",stdout),choice=fgetc(stdin))
{
fputs("Error!Again!\n",stdout);
while(getchar()!=10);
}
while(getchar()!=10);
return toupper(choice);}
short executemenu(int choice,Student *pstudent,Queue *pqueue)
{
printf("You choose '%c'.\n",choice);
switch(choice)
{
case 'E':
if(IsQueueFull(pqueue))
{
fputs("The Queue is FULL!\n",stderr);
break;
}
for(printf("NO.%d name:",pqueue->nodes+1);s_gets(pstudent->name,LEN_NAME);printf("NO.%d name:",pqueue->nodes+1))
{
for(printf("NO.%d score:",pqueue->nodes+1),choice=scanf("%hd",&pstudent->score);
choice!=1||pstudent->score<0||pstudent->score>MAX_SCORE;
printf("NO.%d score:",pqueue->nodes+1),choice=scanf("%hd",&pstudent->score))
{
fputs("Error!Again!\n",stderr);
while(getchar()!=10);
}
while(getchar()!=10);
if(!EnQueue(pstudent,pqueue))
{
fputs("Error!Can't Add Data!\n",stderr);
break;
}
if(IsQueueFull(pqueue))
{
fputs("The Queue is FULL!\n",stderr);
break;
}
}
break;
case 'F':
if(IsQueueEmpty(pqueue))
{
fputs("No Data Found!\n",stderr);
break;
}
for(fputs("Input name(NothingStop):",stdout);s_gets(pstudent->name,LEN_NAME);fputs("Input name(NothingStop):",stdout))
{
SearchQueue(pstudent,pqueue);
}
break;
case 'D':
if(!DeQueue(pstudent,pqueue))
fputs("No Data Found!\n",stderr);
else
fprintf(stdout,"The first Data has been deleted.\n");
break;
case 'C':
EmptyQueue(pstudent,pqueue);
break;
case 'S':
ShowQueue(pqueue);
break;
case 'Q':
return 0;
default:break;
}
return 1;}