/* 范例:9-17 */
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <iomanip.h>
typedef struct node
{
char name[11]; /* 姓名最长10字符 */
int score; /* 成绩 */
struct node *next; /* 指向下一个节点 */
} Node_type;
char choose_menu(void);
Node_type *head; /* 链表开始地址 */
Node_type *tail; /* 链表结尾地址 */
Node_type *nowptr; /* 链表目前节点地址 */
Node_type *prev; /* 记录上一节点地址 */
Node_type *newptr; /* 新增节点地址 */
char str1[11];
void insert_mode(void);
void delete_mode(void);
void show_mode(void);
/* 新增模式 */
void insert_mode(void)
{
char yn='n';
yn='y';
while((tolower(yn)=='y'))
{
newptr = (Node_type *)malloc(sizeof(Node_type));
printf("\n请输入姓名: ");
gets(str1);
if(strlen(str1)>10)
{
str1[10]='\0';
printf("姓名超过长度,已截去!\n\n");
}
strcpy(newptr->name,str1);
printf("请输入分数(0~100): ");
gets(str1);
newptr->score=atoi(str1);
//分数校验,若不在规定范围之内,则不断提示重复操作
while(1)
{
if((newptr->score)<=100 && (newptr->score)>=0)
break;
printf("请重新输入(0~100):");
gets(str1);
newptr->score=atoi(str1);
}
nowptr=head;
if(head==NULL) /* 原先无数据 */
{
newptr->next=NULL;
head=newptr;
tail=newptr;
nowptr=newptr;
}
else
{
/* 插入第一笔前 */
if((newptr->score)>(head->score))
{
newptr->next=head;
head=newptr;
nowptr=newptr;
}
else /* 插到中间 */
{
while(nowptr->next!=NULL)
{
prev=nowptr;
nowptr=nowptr->next;
if((newptr->score)>(nowptr->score))
{
newptr->next=nowptr;
prev->next=newptr;
nowptr=newptr;
break;
}
}
/* 插到结尾 */
if(nowptr==tail && newptr->score<=nowptr->score)
{
nowptr->next=newptr;
newptr->next=NULL;
tail=newptr;
nowptr=newptr;
}
}
}
/* 注意此处千万别自作聪明 free 掉 newptr; */
printf("是否继续?(y/n)");
do
{
yn = getche();
}while(tolower(yn)!='y' && tolower(yn)!='n');
}
}
void delete_mode()
{
Node_type *clear;
char tmpName[11]="";
if(head==NULL) /* 无数据 */
{
printf("\n无数据可输出!\n");
tail=NULL;
return;
}
else
{
printf("\n请输入欲删除的姓名: ");
gets(tmpName);
if(strlen(tmpName)>10)
{
tmpName[10]='\0';
printf("查无此人!\n\n");
return;
}
nowptr=head;
/* 删第一笔 */
if(strcmp(nowptr->name,tmpName)==0)
{
clear=nowptr;
head=nowptr->next;
if(nowptr->next==NULL) /* 只第一笔 */
tail=NULL;
printf("\n%s已删除!\n",clear->name);
free(clear);
return;
}
else
{
prev=nowptr;
while(nowptr->next!=NULL) /* 删除中间的 */
{
nowptr=nowptr->next;
if(strcmp(nowptr->name,tmpName)==0)
{
clear=nowptr;
prev->next=nowptr->next;
printf("\n%s已删除!\n",clear->name);
free(clear);
return;
}
prev=prev->next; /* 上一笔也要跟着+1 */
}
if(nowptr->next == NULL) /* 要删除最后一个节点 */
{
if(strcmp(nowptr->name,tmpName)==0)
{
clear=nowptr;
prev->next=NULL;
tail=prev;
printf("\n%s已删除!\n",clear->name);
free(clear);
return;
}
else
printf("\n查无此人!\n");
}
}
}
}
void show_mode()
{
int count;
count=0;
if(head==NULL)
{
printf("\n\n无数据可显示!\n");
printf("\n\n请按任意键继续....");
getchar();
return;
}
else
{
nowptr=head;
printf("\n\n姓名\t\t分数");
printf("\n====\t\t====\n\n");
while((nowptr->next)!=NULL)
{
printf("%s",nowptr->name);
printf("%*d\n",20-strlen(nowptr->name), nowptr->score);
count++;
nowptr=nowptr->next;
}
printf("%s",nowptr->name);
printf("%*d\n",20-strlen(nowptr->name),nowptr->score);
count++; /* "%*d...",...详见第四章printf()的用法 */
nowptr=nowptr->next;
}
printf("====================\n");
printf("共%d笔数据!\n\n",count);
printf("\n\n请按任意键继续....");
getchar();
}
char choose_menu(void)
{
char option1;
system("cls");
printf("\n************************************");
printf("\n\t1.新增数据");
printf("\n\t2.删除数据");
printf("\n\t3.列出数据");
printf("\n\t4.离开系统");
printf("\n************************************");
printf("\n\t请输入您的选择(1,2,3,4): ");
do
{
option1 = getch();
}while((option1 != '1')&&(option1 != '2')&&(option1 != '3')
&&(option1 != '4'));
return option1;
}
void main(void)
{
char op='1';
while(1)
{
do{
op=choose_menu();
}while(op!='1' && op!='2' &&op!='3' && op!='4');
switch(op)
{
case '1':
insert_mode();
break;
case '2':
delete_mode();
printf("\n\n请按任意键继续...");
getchar();
break;
case '3':
show_mode();
break;
case '4':
return;
}
}
}