1、目 录1 摘要22 功能与数据分析32.1 功能分析32.2 数据分析33 总体设计44 模块介绍54.1 查询功能54.2 修改功能54.3 删除功能74. 输出功能75 编写与测试86 用法说明96.1 在 vc 环境下运行96.2 查询功能96.3 修改功能106.4 删除功能116.5 输出功能127 总结138 附录14摘 要学生信息管理系统的主要的目的在于便于老师掌握学生的信息,对学生的信息进行查询和添加,也有利于学生按各种不同的方式查询、修改自己的信息。 摆脱了曲折的路径,提高了学生相互了解、交流的效率。便于老师、同学及时准确地获得需要的信息。主要通过数组存放数据,应用循环和选择
2、语句对数据实现录入和删除功能。关键词:学生信息,链表,选择结构,循环结构2 功能分析2.1功能分析这是一个便于老师管理,便于学生查询学生信息的一个系统。既然如此,系统必定少不了数据的输入和删除。数据以文件的形式保存在文件中。显示时,数据从文件中输入到显示器。接受数据的是一个结构体链表。查询功能的实现,把数据从文件中取出来。查询可按学号查询和按姓名查询两种方法,按学号查询时,将输入的学号和文件中每个学生的学号比较,如果相等,显示该行的数据到显示器,即是要查找的内容。然后关闭文件。按姓名查询时,将输入的姓名和文件中每个学生的姓名比较,如果相等,显示该行的数据到显示器,即是要查找的内容。然后关闭文件
3、。修改功能的实现,把数据从文件中取出来。进入修改操作时,学生先找到自己的信息,然后选择修改项目:地址、电话或 Email。选择地址项,则输入新地址,把它赋给存储地址的变量。选择电话项,则输入新电话,把它赋给存储电话的变量。选择 Email项,则输入新 Email,把它赋给存储 Email 的变量。然后关闭文件。删除功能的实现,需要首先打开文件,把文件里面的信息全部输入到结构体链表中。把结构体中学生的学号和输入的要删除的学号进行比较,如果相等,则为要删除的项。然后关闭文件。输出功能的实现,把数据从文件中取出来。逐一显示在显示器上,直到全部显示。然后关闭文件。2.2数据分析由于显示的内容包括学号、
4、姓名、年龄、性别、出生年月、地址、电话号码和Email,所以通过一个结构体的链表来实现。写入文件还需要对文件进行操作。需要定义一个指向文件的指针。文件名为“file1.txt”,生成在默认的 vc 的安装目录里边。查询需要输出想要的一些内容,这些数据的类型和结构体的元素的类型一致,所以需要定义一个整型的 num,一个字符数组 name,一个整型的 age,一个字符数组sex,一个字符数组 data,一个字符数组 address,一个字符数组 phone,一个字符数组Email。此外,循环需要整型的数。系统在接受你输入的字符,以判断程序的走向时,还需要一个字符型的变量来接受输入的提示。3 总体设
5、计本程序涉及到几个方面功能:查询,修改,删除和输出。先定义一个结构体变量。通过循环的方式,向变量赋值,采用读的方式打开文件,建立链表,把信息从文件输入到链表中,每输入一个学生的信息,记录学生个数的 n便增加 1,直到输入的学生学号位 0,最后将定义好的宏 NULL 赋给最后一个结点的next 成员。运行程序,显示器上显示查询,修改,删除和输出四项后,要求输入对应的编号。输入号码 1,进入查询项目。查询项目包括按学号查询,按姓名查询和返回。输入号码 2,进入修改项目。其中可以修改地址、电话和 Email。输入号码 3,进入删除项目。输入号码 4,输出学生信息。所显示的内容的进行图表示:(见图 3
6、-1)运行后查询修改删除输出按学号按姓名地址电话Email返回返回图 3-1 显示的结构示意图4 模块介绍4.1 查询功能查询:先选择查询方式,定义一个整变量 num 和一个字符数组 name,输入 num或 name,在 head 不为零和第一节点的 next 不为 0 的前提下,将第一个结点的 num 或name 和输入进来的信息比较,如果不相等,在后移一个结点。若没有要查询的信息,则输出没有要查找的信息。查询的流程图如(图 4-1):按 numY num!=p1-nump1-next!=0YP2=p1P1=P1-nextN num=p1-numYNname!=p1-name,p1-nex
7、t!=0Y P2=p1P1=p1-nextN name=p1-nameY结束NN输入 num输出 p1输出 p1图 4-1“查询 ”流程图4. 2 修改功能先找到自己的信息,再选择需要修改的项目,输入新信息,把它赋给原来的存储变量。修改的流程图如(图 4-2):输入 namenum=p1-numYN 结束Num!=p1-numP1-next!=0N输入 numY P2=p1P1=p1-next输入 nn=1 输入新地址将新地址赋给原地址变量n=2输入新电话将新电话赋给原电话变量n=3输入新 Email将新 Email 赋给原 Email变量图 4-24. 3 删除功能 输入要删除的学号,用相同
8、的方式找到,再删除。输入 numnum!=p1-nump1-next!=0num=p1-numNY结束N输出 p1YP2=p1P1=p1-next4.4 输出功能全部输出:数据在文件中,要把他从里边拿出来,显示在屏幕上。首先打开文件,在内容 p1-num 不等于零时,把里边的内容输出到链表中(循环的方式) 。然后再通过循环,显示链表的内容到显示器。输出的流程图如(图 4-2):打开文件n=0num 为 00!mNY关闭文件n+n=1NYP2-next=p1P2=p1Head=p1P2=p1显示 p1P1=p1-nextP1=NULL结束YN图 4-2“显示”流程图5 调试与测试我在进行程序编写
9、的时候,首先设想好运行画面信息的显示,设计好这个框架。然后在这个框架中对应的地方添加函数,最后在主函数中实现文件的调试是在 vc 中进行。最常见的错误有:某个字符没有定义,结构不匹配,缺少分号等等。但是,此次问题比较严重的是比较简单的语法不熟练,比如给数组赋值时,数组预留的空间不够大,导致和后面的数据连在了一起。再一个就是对文件的操作不是很顺利,文件的输入在此次程序中困扰了一段时间,主要表现是不能从文件中读入数据,在做课程设计之前,我们刚学了文件,可能是自己不认真,没把文件的内容搞清楚,这是其中一个原因。另一个原因是,我做过一个题,是把程序中的数据写到文件中,我的代码是这样的:fp=fopen
10、(“f:sd“,“w“) ,程序能正常运行。所以从文件读入数据时,我的代码是这样的:fp=fopen(“f:sd“,“r“),程序在编译、连接时都没有问题,但在运行时就报错了。起初我怎么调试都没找出问题,因为我从来没怀疑过文件的打开错了,后来我找到了问题,代码应该是这样:fp=fopen(“f:sd.txt“,“r“),文件名后要加上扩展名。但我现在还是不明白,为什么写的时候就可以不加扩展名呢?在文件的输入时还出了这样一个错误, (由于出错误了,我就把可能有错的部分分开单独调试)输入数据后在显示器上显示的数据后面还有一些乱码,这也让我思考良久,通过分析乱码,我找到了错误,错在输入格式时,多加了
11、逗号。总之都是自己的基础不扎实。以上是这次程序设计主要的几处问题的展示。6 用法说明6.1、在 vc6.0 环境下运行次程序,显示为: (如图 6-1) 图 6-1 主显示其中 1 为查询,包括按学号查询和按姓名查询,2 为修改,包括对地址、电话和Email 的修改, 3 是删除学生信息, 4 是输出学生信息。6.2、查询功能:(如图 6-2)图 6-2 查询菜单键盘输入 1 为按学号查询:(如图 6-3)图 6-3 按学号查询键盘输入 2 为按姓名查询:(如图 6-4)图 6-4 按姓名查询6.3、修改功能:主菜单键盘输入 2 进入修改功能菜单:(如图 6-5)图 6-5 修改功能菜单键盘输
12、入 1 为修改地址:(如图 6-6)图 6-6 修改地址键盘输入 2 为修改电话号码:(如图 6-7)图 6-7 修改电话号码键盘输入 3 修改 Email:(如图 6-8)图 6-8 修改 Email6.4、删除功能:(如图 6-9)6-9 删除6.5、输出功能:(如图 6-10)6-10 输出总结课程设计总结通过此次课程设计,我基本上对制作一个相对来说比较完整的程序有了一定的认识和了解。这一周多来的制作,不但对这一学期 C 语言的知识有了一定的巩固,还增加了我们的动手能力。学生信息管理系统,涉及到结构体,链表,文件和循环的知识,所以尤其对这几个方面有所加深和巩固。其中又包括结构体的赋值,写
13、到文件中。从文件中赋值给结构体。此外,还接触到我们平时接触不是很多的函数:fscanf 函数:将数据从文件读入程序。原型:int fscanf(FILE * fp,char format,args,);头文件:#include此外还有 goto 函数.这个系统也存在许多不足:1、 便是大量使用了 goto 函数,导致读程序时有点混乱。2、 当操作错误时,系统不能完全解决。3、 需要在 VC 的环境下才能运行。在做课程设计期间,我发现了自己的许多不足,利用眼前假期的时间,我会好好复习C 语言的知识,为下学期的编程课程打下基础。附录:源程序代码#include#include#include#de
14、fine NULL 0#define LEN sizeof(struct student)struct studentint num ;char name10;int age;char sex5;char data18;char address20;char phone15;char Email20;struct student * next;int n; /n 为全局变量,本文件模块中各函数均可使用它,用来统计学生的数目void main() int n,m;struct student * head;struct student * creat(void);struct student *
15、 rank(struct student * head);void seekxue(struct student * head);void seekxing(struct student * head);struct student * chang(struct student * head);struct student * del(struct student * head);void print(struct student * head);head=creat(); /建立链表,返回头指针head=rank(head);printf(“n“);printf(“n“);printf(“n
16、“);printf(“ *n“);printf(“ 欢迎来到学生信息管理系统n“);printf(“n“);printf(“n“);printf(“n“);ret: printf(“ 主菜单n“);printf(“n“);printf(“ 请选择将要进行的操作n“);printf(“n“);printf(“ 1,查询学生信息n“);printf(“n“);printf(“ 2,修改学生信息n“);printf(“n“);printf(“ 3,删除学生信息n“);printf(“n“);printf(“ 4,输出全部学生信息n“);printf(“n“);printf(“n“);while(1)
17、 scanf(“%d“,switch(n) case 1: sek:printf(“ 请选择查询方式n“);printf(“n“);printf(“ 1,按学号查询n“);printf(“n“);printf(“ 2,按姓名查询n“);printf(“n“);printf(“ 0,返回主菜单n“);printf(“n“);printf(“n“);while(1) scanf(“%d“,switch(m)case 1:seekxue(head); goto sek;case 2:seekxing(head);goto sek;case 0:goto ret;/返回主菜单default:print
18、f(“输入错误,请重新输入n“); case 2:head=chang(head); goto ret;case 3:head=del(head); goto ret;case 4:print(head); goto ret;default:printf(“输入错误,请重新输入n“); void seekxue(struct student * head)/定义按学号查询函数 struct student * p1,*p2;int num,n;loop: printf(“请输入要查询的学生的学号:“);scanf(“%d“,printf(“n“);p1=head;printf(“n“);whi
19、le(num!=p1-nump1=p1-next;/p1 后移一个结点if(num=p1-num)/找到了printf(“他的信息是:n“);printf(“n“);printf(“学号 姓名 年龄 性别 出生年月 地址 电话号码 Email n“);printf(“n“);printf(“%-4d %-7s %-3d %-4s %-9s %-14s %-13s %-15sn“,p1-num,p1-name,p1-age,p1-sex,p1-data,p1-address,p1-phone,p1-Email);printf(“n“);printf(“n“);printf(“ 请选择将要进行的操
20、作n“);printf(“n“);printf(“ 1,继续查询n“);printf(“n“);printf(“ 0,返回上级菜单n“);while(1) scanf(“%d“,switch(n)case 1: goto loop;case 0: goto ret;default: printf(“操作错误,请重新输入n“);else printf(“没有%d 的信息n“,num); printf(“n“);printf(“n“);printf(“ 请选择将要进行的操作n“);printf(“n“);printf(“ 1,继续查询n“);printf(“n“);printf(“ 0,返回上级菜
21、单n“);while(1) scanf(“%d“,switch(n)case 1: goto loop;case 0: goto ret;default: printf(“操作错误,请重新输入n“);ret:printf(“n“);void seekxing(struct student * head)/定义按姓名查询函数 struct student * p1,* p2;int n;char name10;loop: printf(“请输入要查询的学生的姓名:“);scanf(“%s“,name);printf(“n“);p1=head;while(strcmp(name,p1-name)!
22、=0p1=p1-next;/p1 后移一个结点if(strcmp(name,p1-name)=0) /找到了printf(“他的信息是:“);printf(“n“);printf(“学号 姓名 年龄 性别 出生年月 地址 电话号码 Email n“);printf(“n“);printf(“%-4d %-7s %-3d %-4s %-9s %-14s %-13s %-15sn“,p1-num,p1-name,p1-age,p1-sex,p1-data,p1-address,p1-phone,p1-Email);printf(“n“);printf(“n“);printf(“ 请选择将要进行的操
23、作n“);printf(“n“);printf(“ 1,继续查询n“);printf(“n“);printf(“ 0,返回上级菜单n“);while(1) scanf(“%d“,switch(n)case 1: goto loop;case 0: goto ret;default: printf(“操作错误,请重新输入n“);else printf(“没有%s 的信息“,name);printf(“n“);printf(“n“);printf(“ 请选择将要进行的操作n“);printf(“n“);printf(“ 1,继续查询n“);printf(“n“);printf(“ 0,返回上级菜单
24、n“);while(1) scanf(“%d“,switch(n)case 1: goto loop;case 0: goto ret;default: printf(“操作错误,请重新输入n“);ret:printf(“n“);struct student * chang(struct student * head)/定义修改学生信息函数 struct student * p1,*p2;int t,num;char newaddress20;char newphone11;char newEmail20;loop: printf(“请输入你的学号:“);scanf(“%d“,printf(“
25、n“);p1=head;while(num!=p1-nump1=p1-next;/p1 后移一个结点if(num=p1-num)/找到了 lp: printf(“ 请输入要修改的项目n“);printf(“n“);printf(“ 1,地址n“);printf(“n“);printf(“ 2,电话n“);printf(“n“);printf(“ 3,Emailn“);printf(“n“);printf(“ 0,返回主菜单n“);printf(“n“);printf(“n“);while(1)scanf(“%d“,switch(t) case 1:printf(“请输入新地址:“);scanf
26、(“%s“,newaddress);strcpy(p1-address,newaddress);printf(“修改成功n“);goto lp;break;case 2:printf(“请输入新电话号码:“);scanf(“%s“,newphone);strcpy(p1-phone,newphone);printf(“修改成功n“);goto lp;break;case 3:printf(“请输入新 Email:“);scanf(“%s“,newEmail);strcpy(p1-Email,newEmail);printf(“修改成功n“);goto lp;break;case 0:goto
27、ret;default:printf(“操作错误,请重新输入n“);elseprintf(“没有%d 的信息n“,num);printf(“n“);printf(“n“);printf(“ 请选择将要进行的操作n“);printf(“n“);printf(“ 1,重新输入n“);printf(“n“);printf(“ 0,返回主菜单n“);while(1) scanf(“%d“,switch(n)case 1: goto loop;case 0: goto ret;default: printf(“操作错误,请重新输入n“);ret: return(head);struct student
28、* del(struct student * head)/定义删除函数 struct student * p1,*p2;int num,n;loop:printf(“请输入要删除的学生的学号:“);scanf(“%d“,printf(“n“);p1=head;while(num!=p1-nump1=p1-next;/p1 后移一个结点if(num=p1-num)/找到了if(p1=head)head=p1-next;/若 p1 指向的是首结点,把第二个结点地址赋给headelse p2-next=p1-next;/否则将下一结点地址赋给前一结点地址n=n-1;printf(“%d 的信息已删出
29、,他的信息为:n“,num);printf(“n“);printf(“学号 姓名 年龄 性别 出生年月 地址 电话号码 Email n“);printf(“n“);printf(“%-4d %-7s %-3d %-4s %-9s %-14s %-13s %-15sn“,p1-num,p1-name,p1-age,p1-sex,p1-data,p1-address,p1-phone,p1-Email);printf(“n“);printf(“n“);printf(“ 请选择将要进行的操作n“);printf(“n“);printf(“ 1,重新输入n“);printf(“n“);printf(“
30、 0,返回主菜单n“);while(1)scanf(“%d“,switch(n)case 1: goto loop;case 0: goto ret;default:printf(“操作错误,请重新输入n“);free(p1);else printf(“没有%d 的信息n“,num);/找不到该学生信息printf(“ 请选择将要进行的操作n“);printf(“n“);printf(“ 1,重新输入n“);printf(“n“);printf(“ 0,返回主菜单n“);while(1)scanf(“%d“,switch(n)case 1: goto loop;case 0: goto ret
31、;default:printf(“操作错误,请重新输入n“);ret:return(head);void print(struct student * head)/定义输出函数struct student * p;p=head;int n;printf(“n“);printf(“学号 姓名 年龄 性别 出生年月 地址 电话号码 Email n“);printf(“n“);if(head!=NULL)do printf(“%-4d %-7s %-3d %-4s %-9s %-14s %-13s %-15sn“,p-num,p-name,p-age,p-sex,p-data,p-address,p
32、-phone,p-Email);printf(“n“);p=p-next;while(p!=NULL);printf(“ 返回主菜单请输入 0n“);printf(“n“);while(1) scanf(“%d“,if(n=0) goto ret;if(n!=0) printf(“输入错误请重新输入n“);printf(“n“);ret: printf(“n“);struct student * creat(void) /定义输入函数。此函数带回一个指向链表头的指针 struct student * head;struct student * p1,*p2;n=0;p1=p2=(struct
33、student *)malloc(LEN);/开辟一个新单元FILE * fp;fp=fopen(“e:stu.txt“,“r“);fscanf(fp,“%d %s %d %s %s %s %s %s“,head=NULL;while(p1-num!=0) n=n+1;if(n=1)head=p1;else p2-next=p1;p2=p1;p1=(struct student *)malloc(LEN);fscanf(fp,“%d %s %d %s %s %s %s %s“, fclose(fp);p2-next=NULL;return(head);struct student *rank(
34、struct student *head)/定义排序函数struct student *p1,*p2,*p0;int i;p1=head;p0=head;p2=p1-next;if(head=NULL|p1-next=NULL)printf(“Do not need rank“);elsefor(i=1;inext!=NULL)if(p1-nump2-num)if(p1=head)head=p2;else p0-next=p2;p1-next=p2-next;p2-next=p1;p0=p2;p2=p1-next;else if(p1=head)p1=p1-next;p2=p2-next;else p0=p0-next;p1=p1-next;p2=p2-next;if(p1-nump2-num)p0-next=p2;p2-next=p1;p1-next=NULL;p1=head;p0=head;p2=p1-next;return(head);参考书籍:1 谭浩强编著,C 语言程序设计,清华大学出版社,20022 徐连信编著,C 语言程序设计,清华大学出版社,2005