P67 例3-5 设计一个模拟打印任务模拟器运行过程的程序。
头文件:PrintTaskManager.h
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node
{
int id;
char *text;
struct node *next;
}Task;
typedef struct
{
Task *front;
Task *rear;
}Queue;
void InitaskManager(Queue *taskmanager)
{
taskmanager->front=taskmanager->rear=NULL;
}
void AppendPrintTask(Queue *taskmanager,int tid,char *text)
{
Task *p;
p=(Task*)malloc(sizeof(Task));
p->text=(char*)malloc(strlen(text)*sizeof(Task)+1);
strcpy(p->text,text);
p->id=tid;
p->next=NULL;
if(taskmanager->rear!=NULL)
taskmanager->rear->next=p;
taskmanager->rear=p;
if(taskmanager->front==NULL)
taskmanager->front=p;
}
int PrintFirstTask(Queue *taskmanager)
{
Task *p=taskmanager->front;
if(p==NULL)
return 0;
else
{
printf("Task id:%d\n",p->id);
printf("Task context:%s\n",p->text);
}
taskmanager->front=taskmanager->front->next;
if(taskmanager->front==NULL)
taskmanager->rear=NULL;
free(p->text);
free(p);
return 1;
}
void PrintAllTask(Queue *taskmanager)
{
Task *p=taskmanager->front;
while(p!=NULL)
{
printf("Task id:%d\n",p->id);
printf("Task context:%s\n",p->text);
p=p->next;
}
}
void ClearPrintTask(Queue *taskmanager)
{
Task *p,*p1;
p=taskmanager->front->next;
while(p!=NULL)
{
p1=p;
p=p->next;
free(p1->text);
free(p1);
}
}
源文件:例3-5.c
#include"PrintTaskManager.h"
int main()
{
char ch='0';
int tid=0;
char *text="打印内容";
Queue Q;
InitaskManager(&Q);
while(ch!='q')
{
printf("1 加入");
printf("\t2 完成");
printf("\t3 输出");
printf("\t4 清空");
printf("\tq 退出");
printf("\nPlease enter:");
ch=getchar();
getchar();
switch(ch)
{
case '1':
tid=tid+1;
AppendPrintTask(&Q,tid,text);
break;
case'2':
PrintFirstTask(&Q);
break;
case'3':
PrintAllTask(&Q);
break;
case'4':
ClearPrintTask(&Q);
break;
case'q':
return;
}
}
return 0;
}
在VS2019下,需将头文件PrintTaskManager.h第28行的
strcpy(p->text, text);
改为
strcpy_s(p->text, strlen(text) + 1, text);
所以在VS2019下的头文件PrintTaskManager.h为
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node
{
int id;
char *text;
struct node *next;
}Task;
typedef struct
{
Task *front;
Task *rear;
}Queue;
void InitaskManager(Queue *taskmanager)
{
taskmanager->front=taskmanager->rear=NULL;
}
void AppendPrintTask(Queue *taskmanager,int tid,char *text)
{
Task *p;
p=(Task*)malloc(sizeof(Task));
p->text=(char*)malloc(strlen(text)*sizeof(Task)+1);
strcpy_s(p->text,strlen(text)+1,text);
p->id=tid;
p->next=NULL;
if(taskmanager->rear!=NULL)
taskmanager->rear->next=p;
taskmanager->rear=p;
if(taskmanager->front==NULL)
taskmanager->front=p;
}
int PrintFirstTask(Queue *taskmanager)
{
Task *p=taskmanager->front;
if(p==NULL)
return 0;
else
{
printf("Task id:%d\n",p->id);
printf("Task context:%s\n",p->text);
}
taskmanager->front=taskmanager->front->next;
if(taskmanager->front==NULL)
taskmanager->rear=NULL;
free(p->text);
free(p);
return 1;
}
void PrintAllTask(Queue *taskmanager)
{
Task *p=taskmanager->front;
while(p!=NULL)
{
printf("Task id:%d\n",p->id);
printf("Task context:%s\n",p->text);
p=p->next;
}
}
void ClearPrintTask(Queue *taskmanager)
{
Task *p,*p1;
p=taskmanager->front->next;
while(p!=NULL)
{
p1=p;
p=p->next;
free(p1->text);
free(p1);
}
}
其中头文件PrintTaskManager.h的清空打印队列部分
void ClearPrintTask(Queue *taskmanager)
{
Task *p,*p1;
p=taskmanager->front->next;
while(p!=NULL)
{
p1=p;
p=p->next;
free(p1->text);
free(p1);
}
}
最好改为
void ClearPrintTask(Queue *taskmanager)
{
Task *now=taskmanager->front,*next=NULL;
while(now!=NULL)
{
next=now->next;
free(now->text);
free(now);
now=next;
}
taskmanager->front=taskmanager->rear=NULL;
}
这种更简洁,避免了前者的逻辑混乱。