no&&p!=NULL) /*作学号比较*/ {q=p; /*待排序点值小,则新表指针后移*/ p=p->next; }
if(p==q) /*p==q,说明待排序点值大,应排在首位*/ {
t->next=p; /*待排序点的后继为p*/ h=t; /*新头结点为待排序点*/ }
else /*待排序点应插入在中间某个位置q和p之间,如p为空则是尾部*/ {
t->next=p; /*t的后继是p*/ q->next=t; /*q的后继是t*/ } }
p=h; /*已排好序的头指针赋给p,准备填写名次*/ while(p!=NULL) /*当p不为空时,进行下列操作*/ {
i++; /*结点序号*/
p->order=i; /*将名次赋值*/ p=p->next; /*指针后移*/ }
printf(\"sort sucess!!!\\n\"); /*排序成功*/ return h; /*返回头指针*/ }
STUDENT *insert(STUDENT *h) {
STUDENT *p,*q,*info; /*p指向插入位置,q是其前驱,info指新插入记录*/ char s[11]; /*保存插入点位置的学号*/ int s1,i;
printf(\"please enter location before the no\\n\"); scanf(\"%s\输入插入点学号*/
printf(\"\\nplease new record\\n\"); /*提示输入记录信息*/ info=(STUDENT *)malloc(sizeof(STUDENT)); /*申请空间*/ if(!info) {
printf(\"\\nout of memory\"); /*如没有申请到,内存溢出*/ return NULL; /*返回空指针*/ }
inputs(\"enter no:\输入学号并校验*/
inputs(\"enter name:\输入姓名,并进行校验*/ inputs(\"enter sex:\输入性别,并进行校验*/
inputs(\"enter major:\输入专业名,并进行校验*/ inputs(\"enter class:\输入班级名,并进行校验*/ inputs(\"enter tele:\输入电话,并进行校验*/
inputs(\"enter address:\输入地址,并进行校验*/ info->order=0; /*名次赋值0*/ info->next=NULL; /*设后继指针为空*/ p=h; /*将指针赋值给p*/ q=h; /*将指针赋值给q*/
while(strcmp(p->no,s)&&p!=NULL) /*查找插入位置*/ {
q=p; /*保存指针p,作为下一个p的前驱*/ p=p->next; /*将指针p后移*/ }
if(p==NULL) /*如果p指针为空,说明没有指定结点*/ if(p==h) /*同时p等于h,说明链表为空*/ h=info; /*新记录则为头结点*/ else
q->next=info; /*p为空,但p不等于h,将新结点插在表尾*/ else
if(p==h) /*p不为空,则找到了指定结点*/ {
info->next=p; /*如果p等于h,则新结点插入在第一个结点之前*/ h=info; /*新结点为新的头结点*/ } else {
info->next=p; /*不是头结点,则是中间某个位置,新结点的后继为p*/ q->next=info; /*新结点作为q的后继结点*/ }
printf(\"\\n ----have inserted %s student----\\n\forget save---\\n\"); /*提示存盘*/ return(h); /*返回头指针*/ }
/* 从文件读数据*/ STUDENT *load() {
STUDENT *p,*q,*h=NULL; /*定义记录指针变量*/ FILE *fp; /* 定义指向文件的指针*/ char infile[10]; /*保存文件名*/
printf(\"Enter infile name,for example c:\\\\f1\\\e.txt:\\n\"); scanf(\"%s\/*输入文件名*/
if((fp=fopen(infile,\"rb\"))==NULL) /*打开一个二进制文件,为读方式*/ {
printf(\"can not open file\\n\"); /*如不能打开,则结束程序*/ exit(1); }
printf(\"\\n -----Loading file!-----\\n\");
p=(STUDENT *)malloc(sizeof(STUDENT)); /*申请空间*/ if(!p) {
printf(\"out of memory!\\n\"); /*如没有申请到,则内存溢出*/ return h; /*返回空头指针*/ }
h=p; /*申请到空间,将其作为头指针*/ while(!feof(fp)) /*循环读数据直到文件尾结束*/ {
if(1!=fread(p,sizeof(STUDENT),1,fp)) break; /*如果没读到数据,跳出循环*/
p->next=(STUDENT *)malloc(sizeof(STUDENT)); /*为下一个结点申请空间*/ if(!p->next) {
printf(\"out of memory!\\n\"); /*如没有申请到,则内存溢出*/ return h; }
q=p; /*保存当前结点的指针,作为下一结点的前驱*/ p=p->next; /*指针后移,新读入数据链到当前表尾*/ }
q->next=NULL; /*最后一个结点的后继指针为空*/ fclose(fp); /*关闭文件*/
printf(\"---You have success read data from file!!!---\\n\"); return h; /*返回头指针*/ } /*保存数据到文件*/ void save(STUDENT *h) {
FILE *fp; /*定义指向文件的指针*/ STUDENT *p; /* 定义移动指针*/
char outfile[10]; /*保存输出文件名*/
printf(\"Enter outfile name,for example c:\\\\f1\\\e.txt:\\n\"); /*提示文件名格式信息*/
scanf(\"%s\
if((fp=fopen(outfile,\"wb\"))==NULL) /*为输出打开一个二进制文件,如没有则建立*/ {
printf(\"can not open file\\n\"); exit(1); }
printf(\"\\nSaving file......\\n\"); /*打开文件,提示正在保存*/ p=h; /*移动指针从头指针开始*/ while(p!=NULL) /*如p不为空*/ {
fwrite(p,sizeof(STUDENT),1,fp);/*写入一条记录*/
p=p->next; /*指针后移*/ }
fclose(fp); /*关闭文件*/
printf(\"-----save success!!-----\\n\"); /*显示保存成功*/ }
实验4:/***********xuesheng.c***********/ /******头文件(.h)***********/ #include \"stdio.h\" /*I/O函数*/ #include \"stdlib.h\" /*其它说明*/ #include \"string.h\" /*字符串函数*/ #include \"conio.h\" /*屏幕操作函数*/ #include \"mem.h\" /*内存操作函数*/ #include \"ctype.h\" /*字符操作函数*/
#include \"alloc.h\" /*动态地址分配函数*/ #define N 3 /*定义常数*/
typedef struct z1 /*定义数据结构*/ {
char no[11]; char name[15]; char sex[5]; char major[15]; char class[15]; char tele[15]; char address[15]; int order;
struct z1 *next; }STUDENT;
/*以下是函数原型*/
STUDENT *init(); /*初始化函数*/ STUDENT *create(); /*创建链表*/ void edit(); /*修改记录*/
STUDENT *dele(STUDENT *h); /*删除记录*/ void print(STUDENT *h); /* 显示所有记录*/ void search1(STUDENT *h); /*查找*/ void search2(STUDENT *h); /*查找*/ void search3(STUDENT *h); /*查找*/ STUDENT *sort(STUDENT *h); /*排序*/
int menu_select(); /*菜单函数*/ void save(STUDENT *h); /*保存*/ STUDENT *load(); /*读入记录*/
void inputs(char *prompt, char *s, int count); /******主函数开始*******/ main() {
int i;
STUDENT *head; /*链表定义头指针*/ head=init(); /*初始化链表*/ clrscr(); /*清屏*/ for(;;) /*无限循环*/ {
switch(menu_select()) /*调用主菜单函数,返回值整数作开关语句的条件*/
{ /*值不同,执行的函数不同,break 不能省略*/ case 0:head=init();break; /*执行初始化*/ case 1:head=create();break; /*创建链表*/
case 2:print(head);break; /*显示全部记录*/ case 3:edit();break; /*修改记录*/
case 4:head=dele(head);break; /*删除记录*/ case 5:head=sort(head);break; /*排序*/ case 6:search1(head);break; /*查找记录*/ case 7:search2(head);break; /*查找记录*/ case 8:search3(head);break; /*查找记录*/ case 9:save(head);break; /*保存文件*/ case 10: head=load(); break; /*读文件*/
case 11:exit(0); /*如菜单返回值为14程序结束*/} } }
/*菜单函数,返回值为整数*/ int menu_select() {
char *menu[]={\"***************MENU***************\定义菜单字符串数组*/ \" 0. init list\初始化*/ \" 1. Input\输入记录*/ \" 2. List\显示记录*/
\" 3. Edit \修改记录*/ \" 4. Delete\删除记录*/ \" 5. Sort\排序*/
\" 6. Seek(name)\查找*/ \" 7. Seek(number)\查找*/ \" 8. Seek(class)\查找*/ \" 9. Save\保存*/
\" 10. Load\从文件中读入记录*/ \" 11.Quit\退出*/ \" \ \" \ \" \
char s[3]; /*以字符形式保存选择号*/ int c,i; /*定义整形变量*/ gotoxy(1,25); /*移动光标*/
printf(\"press any key enter menu......\\n\"); /*压任一键进入主菜单*/ getch(); /*输入任一键*/ clrscr(); /*清屏幕*/ gotoxy(1,1); /*移动光标*/
textcolor(YELLOW); /*设置文本显示颜色为黄色*/ textbackground(BLUE); /*设置背景颜色为蓝色*/ gotoxy(10,2); /*移动光标*/
putch(0xc9); /*输出左上角边框┏*/ for(i=1;i<44;i++)
putch(0xcd); /*输出上边框水平线*/
putch(0xbb); /*输出右上角边框 ┓*/ for(i=3;i<20;i++) {
gotoxy(10,i);putch(0xba); /*输出左垂直线*/
gotoxy(,i);putch(0xba); } /*输出右垂直线*/
gotoxy(10,20);putch(0xc8); /*输出左上角边框┗*/ for(i=1;i<44;i++)
putch(0xcd); /*输出下边框水平线*/
putch(0xbc); /*输出右下角边框┛*/
window(11,3,53,19); /* 制作显示菜单的窗口,大小根据菜单条数设计*/ clrscr(); /*清屏*/
for(i=0;i<16;i++) /*输出主菜单数组*/ {
gotoxy(10,i+1);
cprintf(\"%s\ }
textbackground(BLACK); /*设置背景颜色为黑色*/ window(1,1,80,25); /*恢复原窗口大小*/ gotoxy(10,21); /*移动光标*/ do{
printf(\"\\n Enter you choice(0~11):\"); /*在菜单窗口外显示提示信息*/ scanf(\"%s\输入选择项*/
c=atoi(s); /*将输入的字符串转化为整形数*/ }while(c<0||c>11); /*选择项不在0~11之间重输*/
return c; /*返回选择项,主程序根据该数调用相应的函数*/ }
STUDENT *init() {
return NULL; }
/*创建链表*/
STUDENT *create() {
int i; int s;
STUDENT *h=NULL,*info; /* STUDENT指向结构体的指针*/ for(;;) {
info=(STUDENT *)malloc(sizeof(STUDENT)); /*申请空间*/ if(!info) /*如果指针info为空*/ {
printf(\"\\nout of memory\"); /*输出内存溢出*/ return NULL; /*返回空指针*/ }
inputs(\"enter no:(If you want to end,press @ )\输入学号并校验*/
if(info->no[0]=='@') break; /*如果学号首字符为@则结束输入*/ inputs(\"enter name:\输入姓名,并进行校验*/ inputs(\"enter sex:\输入性别,并进行校验*/
inputs(\"enter major:\输入专业名,并进行校验*/ inputs(\"enter class:\输入班级名,并进行校验*/ inputs(\"enter tele:\输入电话,并进行校验*/
inputs(\"enter address:\输入地址,并进行校验*/ info->next=h; /*将头结点做为新输入结点的后继结点*/
h=info; /*新输入结点为新的头结点*/ }
return(h); /*返回头指针*/ }
/*输入字符串,并进行长度验证*/
void inputs(char *prompt, char *s, int count) { char p[255]; do{
printf(prompt); /*显示提示信息*/ scanf(\"%s\输入字符串*/
if(strlen(p)>count)printf(\"\\n too long! \\n\"); /*进行长度校验,超过count值重输入*/
}while(strlen(p)>count);
strcpy(s,p); /*将输入的字符串拷贝到字符串s中*/ }
/*输出链表中结点信息*/ void print(STUDENT *h) {
int i=0; /* 统计记录条数*/ STUDENT *p; /*移动指针*/ clrscr(); /*清屏*/
p=h; /*初值为头指针*/
printf(\"\\n\\n\\n****************************STUDENT********************************\\n\");
printf(\"|rec|nO | name | sex |major|class | tele | address |\\n\"); printf(\"|---|-----|----------|-----|-----|------|----------|-----------|\\n\"); while(p!=NULL) {
i++;
printf(\"|%3d|%-5s|%-10s|%5s|%5s|%6s|%10s|%11s|\\n\i, p->no,p->name,p->sex,p->major,p->class,p->tele,p->address); p=p->next; }
printf(\"**********************************end*********************************\\n\"); }
/*删除记录*/
STUDENT *dele(STUDENT *h) {
STUDENT *p,*q; /*p为查找到要删除的结点指针,q为其前驱指针*/ char s[11]; /*存放学号*/ clrscr(); /*清屏*/
printf(\"please deleted no\\n\"); /*显示提示信息*/ scanf(\"%s\输入要删除记录的学号*/ q=p=h; /*给q和p赋初值头指针*/
while(strcmp(p->no,s)&&p!=NULL) /*当记录的学号不是要找的,或指针不为空时*/ {
q=p; /*将p指针值赋给q作为p的前驱指针*/ p=p->next; /*将p指针指向下一条记录*/ }
if(p==NULL) /*如果p为空,说明链表中没有该结点*/ printf(\"\\nlist no %s student\\n\
else /*p不为空,显示找到的记录信息*/ {
printf(\"\\n\\n\\n****************************STUDENT********************************\\n\");
printf(\"|nO | name | sex |major|class | tele | address |\\n\");
printf(\"|---|-----|----------|-----|-----|------|----------|-----------|\\n\");
printf(\"|%-5s|%-10s|%5s|%5s|%6s|%10s|%11s|\\n\s,p->tele,p->address);
printf(\"********************************end*******************************\\n\"); getch(); /*压任一键后,开始删除*/
if(p==h) /*如果p==h,说明被删结点是头结点*/ h=p->next; /*修改头指针指向下一条记录*/ else
q->next=p->next; /*不是头指针,将p的后继结点作为q的后继结点*/ free(p); /*释放p所指结点空间*/
printf(\"\\n have deleted No %s student\\n\
printf(\"Don't forget save\\n\");/*提示删除后不要忘记保存文件*/ }
return(h); /*返回头指针*/ }
/*查找记录*/
void search1(STUDENT *h) {
STUDENT *p; /* 移动指针*/
char s[15]; /*存放姓名的字符数组*/ clrscr(); /*清屏幕*/
printf(\"please enter name for search\\n\"); scanf(\"%s\输入姓名*/ p=h; /*将头指针赋给p*/
while(strcmp(p->name,s)&&p!=NULL) /*当记录的姓名不是要找的,或指针不为空时*/ p=p->next; /*移动指针,指向下一结点*/ if(p==NULL) /*如果指针为空*/
printf(\"\\nlist no %s student\\n\显示没有该学生*/ else /*显示找到的记录信息*/
{printf(\"\\n\\n\\n****************************STUDENT********************************\\n\");
printf(\"|nO | name | sex |major|class | tele | address |\\n\"); printf(\"|-----|----------|-----|-----|------|----------|-----------|\\n\") ;
printf(\"|%-5s|%-10s|%5s|%5s|%6s|%10s|%11s|\\n\s,p->tele,p->address);
printf(\"********************************end*******************************\\n\"); }
}
/*查找记录*/
void search2(STUDENT *h) {
STUDENT *p; /* 移动指针*/
char s[15]; /*存放学号的字符数组*/ clrscr(); /*清屏幕*/
printf(\"please enter number for search\\n\"); scanf(\"%s\输入学号*/ p=h; /*将头指针赋给p*/
while(strcmp(p->no,s)&&p!=NULL) /*当记录的学号不是要找的,或指针不为空时*/ p=p->next; /*移动指针,指向下一结点*/ if(p==NULL) /*如果指针为空*/
printf(\"\\nlist no %s student\\n\显示没有该学生*/ else /*显示找到的记录信息*/
{printf(\"\\n\\n\\n****************************STUDENT********************************\\n\");
printf(\"|nO | name | sex |major|class | tele | address |\\n\"); printf(\"|-----|----------|-----|-----|------|----------|-----------|\\n\") ;
printf(\"|%-5s|%-10s|%5s|%5s|%6s|%10s|%11s|\\n\s,p->tele,p->address);
printf(\"********************************end*******************************\\n\"); } }
/*查找记录*/
void search3(STUDENT *h) {
STUDENT *p; /* 移动指针*/
char s[15]; /*存放班级的字符数组*/ clrscr(); /*清屏幕*/
printf(\"please enter class for search\\n\"); scanf(\"%s\输入姓名*/ p=h; /*将头指针赋给p*/
while(strcmp(p->class,s)&&p!=NULL) /*当记录的班级不是要找的,或指针不为空时*/ p=p->next; /*移动指针,指向下一结点*/ if(p==NULL) /*如果指针为空*/
printf(\"\\nlist no %s student\\n\显示没有该学生*/ else /*显示找到的记录信息*/
{printf(\"\\n\\n\\n****************************STUDENT********************************\\n\");
printf(\"|nO | name | sex |major|class | tele | address |\\n\"); printf(\"|-----|----------|-----|-----|------|----------|-----------|\\n\") ;
printf(\"|%-5s|%-10s|%5s|%5s|%6s|%10s|%11s|\\n\s,p->tele,p->address);
printf(\"********************************end*******************************\\n\");
} }
/*保存数据到文件*/ void save(STUDENT *h) {
FILE *fp; /*定义指向文件的指针*/ STUDENT *p; /* 定义移动指针*/
char outfile[10]; /*保存输出文件名*/
printf(\"Enter outfile name,for example c:\\\\f1\\\e.txt:\\n\"); /*提示文件名格式信息*/
scanf(\"%s\
if((fp=fopen(outfile,\"wb\"))==NULL) /*为输出打开一个二进制文件,如没有则建立*/ {
printf(\"can not open file\\n\"); exit(1); }
printf(\"\\nSaving file......\\n\"); /*打开文件,提示正在保存*/ p=h; /*移动指针从头指针开始*/ while(p!=NULL) /*如p不为空*/ {
fwrite(p,sizeof(STUDENT),1,fp);/*写入一条记录*/ p=p->next; /*指针后移*/ }
fclose(fp); /*关闭文件*/
printf(\"-----save success!!-----\\n\"); /*显示保存成功*/ }
/* 从文件读数据*/ STUDENT *load() {
STUDENT *p,*q,*h=NULL; /*定义记录指针变量*/ FILE *fp; /* 定义指向文件的指针*/ char infile[10]; /*保存文件名*/ printf(\"Enter infile name,for example c:\\\\f1\\\e.txt:\\n\"); scanf(\"%s\/*输入文件名*/
if((fp=fopen(infile,\"rb\"))==NULL) /*打开一个二进制文件,为读方式*/ {
printf(\"can not open file\\n\"); /*如不能打开,则结束程序*/ exit(1); }
printf(\"\\n -----Loading file!-----\\n\");
p=(STUDENT *)malloc(sizeof(STUDENT)); /*申请空间*/ if(!p) {
printf(\"out of memory!\\n\"); /*如没有申请到,则内存溢出*/ return h; /*返回空头指针*/ }
h=p; /*申请到空间,将其作为头指针*/ while(!feof(fp)) /*循环读数据直到文件尾结束*/ {
if(1!=fread(p,sizeof(STUDENT),1,fp)) break; /*如果没读到数据,跳出循环*/
p->next=(STUDENT *)malloc(sizeof(STUDENT)); /*为下一个结点申请空间*/ if(!p->next) {
printf(\"out of memory!\\n\"); /*如没有申请到,则内存溢出*/ return h; }
q=p; /*保存当前结点的指针,作为下一结点的前驱*/ p=p->next; /*指针后移,新读入数据链到当前表尾*/ }
q->next=NULL; /*最后一个结点的后继指针为空*/ fclose(fp); /*关闭文件*/
printf(\"---You have success read data from file!!!---\\n\"); return h; /*返回头指针*/ }
/*排序*/
STUDENT *sort(STUDENT *h) {
int i=0; /*保存名次*/ STUDENT *p,*q,*t,*h1; /*定义临时指针*/
h1=h->next; /*将原表的头指针所指的下一个结点作头指针*/ h->next=NULL; /*第一个结点为新表的头结点*/ while(h1!=NULL) /*当原表不为空时,进行排序*/ {
t=h1; /*取原表的头结点*/
h1=h1->next; /*原表头结点指针后移*/
p=h; /*设定移动指针p,从头指针开始*/
q=h; /*设定移动指针q做为p的前驱,初值为头指针*/ while(t->nono&&p!=NULL) /*作学号比较*/ {q=p; /*待排序点值小,则新表指针后移*/ p=p->next; }
if(p==q) /*p==q,说明待排序点值大,应排在首位*/ {
t->next=p; /*待排序点的后继为p*/ h=t; /*新头结点为待排序点*/ }
else /*待排序点应插入在中间某个位置q和p之间,如p为空则是尾部*/ {
t->next=p; /*t的后继是p*/ q->next=t; /*q的后继是t*/ } }
p=h; /*已排好序的头指针赋给p,准备填写名次*/ while(p!=NULL) /*当p不为空时,进行下列操作*/ {
i++; /*结点序号*/
p->order=i; /*将名次赋值*/
p=p->next; /*指针后移*/ }
printf(\"sort sucess!!!\\n\"); /*排序成功*/ return h; /*返回头指针*/ }
/*追加记录到文件*/ void edit() {
FILE *fp; /*定义指向文件的指针*/ STUDENT *info; /*新记录指针*/ int s1,i;
char infile[10]; /*保存文件名*/ printf(\"\\nplease new record\\n\");
info=(STUDENT *)malloc(sizeof(STUDENT)); /*申请空间*/ if(!info) {
printf(\"\\nout of memory\"); /*没有申请到,内存溢出本函数结束*/ return ; }
inputs(\"enter no:\输入学号并校验*/
inputs(\"enter name:\输入姓名,并进行校验*/ inputs(\"enter sex:\输入性别,并进行校验*/
inputs(\"enter major:\输入专业名,并进行校验*/ inputs(\"enter class:\输入班级名,并进行校验*/ inputs(\"enter tele:\输入电话,并进行校验*/
inputs(\"enter address:\输入地址,并进行校验*/ info->next=NULL; /*将新记录后继指针赋值为空*/ printf(\"Enter infile name,for example c:\\\\f1\\\e.txt:\\n\"); scanf(\"%s\/*输入文件名*/
if((fp=fopen(infile,\"ab\"))==NULL) /*向二进制文件尾增加数据方式打开文件*/ {
printf(\"can not open file\\n\"); /*显示不能打开*/ exit(1); /*退出程序*/ }
printf(\"\\n -----Edit record!-----\\n\");
if(1!=fwrite(info,sizeof(STUDENT),1,fp)) /*写文件操作*/ {
printf(\"-----file write error!-----\\n\"); return; /*返回*/ }
printf(\"-----edit sucess!!----\\n\"); fclose(fp); /*关闭文件*/ }