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; }这种更简洁,避免了前者的逻辑混乱。