C语言课程设计--学生信息管理系统

zhaoyongu

贡献于2013-03-12

字数:11124 关键词: C/C++开发

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

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 8 金币 [ 分享文档获得金币 ]
0 人已下载

下载文档

相关文档