●题目名称
C语言学生信息管理系统
●题目分析
将文件引入学生信息管理系统,完善学生信息数据的处理,包括信息的读取、保存、刷新。编写与文件有关的程序,需要考虑将对文件以什么方式操作,文件能否被打开,文件在什么位置。为了程序的可读性,一般将文件的读取、存盘、操作自定义为函数。
●算法构造
●●刷新学生信息update()函数
<1>以只读方式打开指定文件,判断文件是否为空,若为空,则提示:文件为空!
<2>循环读入学生信息,并累加当前记录的学生人数n
<3>输出提示:刷新成功!
<4>关闭文件
●●查询学生信息seek()函数
<1>用户输入要进行的操作:1.按学号查询;2.按姓名查询;3.退出本菜单
<2>选择1:输入要查询的学生的学号;判断输入的学号和存好的学号一致;一致则输出学生的信息,不一致则输出:该学号不存在!
<3>选择2:输入要查询的学生的姓名;判断输入的姓名和存好的姓名一致;一致则输出学生的信息,不一致则输出:该姓名不存在!
●●修改学生信息modify()函数
<1>输入要修改的学生的学号
<2>比较输入的学号和文件存好的学号是否一致,选择要进行的操作编号:1.修改姓名;2.修改年龄;3.修改性别;4.修改C语言成绩;5.修改高等数学成绩;6.修改大学英语成绩;7.退出本菜单
<3>选择1:输入新的姓名s2;新的姓名s2替换原来的姓名;保存新的姓名
<4>选择2:输入新的年龄age;新的姓名age替换原来的年龄;保存新的年龄
<5>选择3:输入新的性别sex1;新的性别sex1替换原来的性别;保存新的性别
<6>选择4:输入新的C语言成绩score1;新的C语言成绩score1替换原来的C语言成绩;保存新的C语言成绩
<7>选择5:输入新的高等数学成绩score1;新的高等数学成绩score1替换原来的高等数学成绩;保存新的高等数学成绩
<8>选择6:输入新的大学英语成绩score1;新的大学英语成绩score1替换原来的姓名;保存新的大学英语成绩
<9>选择7:返回主菜单
●●插入学生信息函数insert()函数
<1>输入待增加的学生数n
<2>循环依次输入每个学生的学号、姓名、性别、年龄、C语言成绩、高等数学成绩、大学英语成绩
<3>将这些信息依次写入文件
<4>提示:添加成功!
<5>调用按学号排序函数,将信息排序好
<5>关闭文件
●●按学号删除信息del()函数
<1>输入要删除学生的学号s1
<2>初始化flag=0,进入循环,比较输入的学号和文件记录的学号是否一致,若一致则令flag=1,循环将后面的学生记录向前移动
<3>判断flag=0,提示:该学号不存在!
<4>判断flag=1,学生人数-1并保存,提示:删除成功!
<5>关闭文件
●●显示当前信息display()函数
<1>打开文件
<2>读取文件信息;若文件为空,则提示:文件为空!若文件不为空,则循环依次输出每个学生的学号、姓名、性别、年龄、C语言成绩、高等数学成绩、大学英语成绩
<3>关闭文件
●●保存当前学生信息fileWrite()函数
<1>打开文件
<2>读取文件信息;若文件为空,则提示:文件为空!若文件不为空,则循环依次写入每个学生的学号、姓名、性别、年龄、C语言成绩、高等数学成绩、大学英语成绩
<3>关闭文件
●源代码
#include<stdio.h> /*I/O函数*/ #include<stdlib.h> /*其它说明*/ #include<string.h>
/*字符串函数*/ #define max 100 #define LEN 15 /* 学号和姓名最大字符数,实际请更改*/ #define N 100 /*
最大学生人数,实际请更改*/ int k=1,n=0, m=0;/* n代表当前记录的学生人数*/ //学生信息结构体 struct student {
char no[LEN];//学号 char name[LEN];//姓名 char sex[LEN];//性别 int age;//年龄 float
C;//c语言成绩 float M;//数学成绩 float E;//英语成绩 }stu[N]; void fileWrite(); //系统帮助及说明
void help() { printf("\n0.欢迎使用系统帮助!\n"); printf("\n1.初次进入系统后,请先选择增加学生信息;\n");
printf("\n2.按照菜单提示键入数字代号;\n"); printf("\n3.增加学生信息后,切记保存;\n");
printf("\n4.谢谢您的使用!\n"); } //刷新学生信息 void update() { int j=0; FILE * fp;
if((fp=fopen("student.txt","r"))==NULL) printf("文件为空!\n");
while(fscanf(fp,"%s,%s,%s,%d,%f,%f,%f\n",&stu[j].no,&stu[j].name,&stu[j].sex,&stu[j].age,&stu[j].C,&stu[j].M,&stu[j].E)==7)
//从文件中读取信息 { j++; } n=j; printf("\n 提示:刷新成功!!! \n"); fclose(fp); } //查询学生信息
void seek() { int j=0; FILE * fp; if((fp=fopen("student.txt","r"))==NULL)
return ; while(fscanf(fp,"%s %s %s %d %f %f
%f",&stu[j].no,&stu[j].name,&stu[j].sex,&stu[j].age,&stu[j].C,&stu[j].M,&stu[j].E)==7)
{ j++; } n=j; int i=0,item,flag; char s1[LEN+1]; /* 以姓名和学号最长长度+1为准*/
printf("----------------------\n"); printf("-----1.按学号查询-----\n");
printf("-----2.按姓名查询-----\n"); printf("-----3.退出本菜单-----\n");
printf("----------------------\n"); while(1) { printf("请选择子菜单编号:");
scanf("%d",&item); //用户输入要进行的操作 flag=0; switch(item) { case 1:
printf("请输入要查询的学生的学号:\n"); scanf("%s",&s1); for(i=0; i<n; i++) //n代表当前记录的学生人数
if(strcmp(s1,stu[i].no)==0) //strcmp()是字符串比较函数,判断输入的学号和存好的学号一致 { flag=1;
printf("学生学号 学生姓名 年龄 性别 C语言成绩 高等数学 大学英语成绩\n");
printf("--------------------------------------------------------------------\n");
printf("%s %16s %10s %10d %10.1f %10.1f
%10.1f\n",stu[i].no,stu[i].name,stu[i].sex,stu[i].age,stu[i].C,stu[i].M,stu[i].E);
//输出学生的信息 } if(0==flag) //输入的学号和存好的学号不一致 printf("该学号不存在!\n"); break; case 2:
printf("请输入要查询的学生的姓名:\n"); scanf("%s",&s1); //输入学生姓名 for(i=0; i<n; i++)
if(strcmp(stu[i].name,s1)==0) //输入的姓名和存好的姓名一致 { flag=1; printf("学生学号 学生姓名 年龄 性别
C语言成绩 高等数学 大学英语成绩\n");
printf("--------------------------------------------------------------------\n");
printf("%s %16s %10s %10d %10.1f %10.1f
%10.1f\n",stu[i].no,stu[i].name,stu[i].sex,stu[i].age,stu[i].C,stu[i].M,stu[i].E);
//输出学生的信息 } if(0==flag) //输入的姓名和存好的姓名不一致 printf("该姓名不存在!\n"); break; case 3:
return; default: printf("请在1-3之间选择\n"); } } } //修改学生信息 void modify() { int j=0;
FILE * fp; if((fp=fopen("student.txt","r"))==NULL) { printf("\n
警告:打开文件错误,请退出重新打开!\n"); system("pause"); exit(0); } while(fscanf(fp,"%s %s %s
%d %f %f
%f",&stu[j].no,&stu[j].name,&stu[j].sex,&stu[j].age,&stu[j].C,&stu[j].M,&stu[j].E)==7)
{ j++; } n=j; int i,item=0,num; int age; char sex1[4],s1[LEN+1],s2[LEN+1]; /*
以姓名和学号最长长度+1为准*/ float score1; printf("请输入要修改的学生的学号:"); scanf("%s",s1);
for(i=0;i<n;i++) { if(strcmp(stu[i].no,s1)==0) /*比较字符串是否相等*/ { num=i; //给num赋i值
printf("------------------\n"); printf("1.修改姓名\n"); printf("2.修改年龄\n");
printf("3.修改性别\n"); printf("4.修改C语言成绩\n"); printf("5.修改高等数学成绩\n");
printf("6.修改大学英语成绩\n"); printf("7.退出本菜单\n"); printf("------------------\n");
while(1) { printf("请选择子菜单编号:"); scanf("%d",&item); switch(item) { case 1:
printf("请输入新的姓名:"); scanf("%s",s2); strcpy(stu[num].name,s2);
//strcpy()是字符串复制函数,将新输入的值赋给原先的值 fileWrite(); break; case 2: printf("请输入新的年龄:");
scanf("%d",&age); stu[num].age=age; fileWrite(); break; case 3:
printf("请输入新的性别:"); scanf("%s",&sex1); strcpy(stu[num].sex,sex1); fileWrite();
break; case 4: printf("请输入新的C语言成绩:"); scanf("%d",&score1); stu[num].C=score1;
fileWrite(); break; case 5: printf("请输入新的高等数学成绩:"); scanf("%d",&score1);
stu[num].M=score1; fileWrite(); break; case 6: printf("请输入新的大学英语成绩:");
scanf("%d",&score1); stu[num].E=score1; fileWrite(); break; case 7: return;
default: printf("请在1-7之间选择\n"); } } } else { printf("没有该学生学号!!!"); } } }
//按学号排序函数 void sort() { int i,j,*p,*q,s; char temp[LEN+1],ctemp[LEN]; float
*x,*y,z; float *a,*b,c; float *k,*l,h; for(i=0;i<n-1;i++) { for(j=n-1;j>i;j--)
if(strcmp(stu[j-1].no,stu[j].no)>0) { strcpy(temp,stu[j-1].no);
strcpy(stu[j-1].no,stu[j].no); strcpy(stu[j].no,temp);
strcpy(temp,stu[j-1].name); strcpy(stu[j-1].name,stu[j].name);
strcpy(stu[j].name,temp); p=&stu[j-1].age; q=&stu[j].age; s=*q; *q=*p; *p=s;
strcpy(ctemp,stu[j-1].sex); strcpy(stu[j-1].sex,stu[j].sex);
strcpy(stu[j].sex,ctemp); x=&stu[j-1].C; y=&stu[j].C; z=*x; *x=*y; *y=z;
a=&stu[j-1].M; b=&stu[j].M; c=*a; *a=*b; *b=c; k=&stu[j-1].E; l=&stu[j].E;
h=*k; *k=*l; *l=h; } } } //插入学生信息函数 void insert() { int i;
printf("请输入待增加的学生数:"); scanf("%d",&n); FILE * fp;
if((fp=fopen("student.txt","at"))==NULL) printf("文件为空!\n"); for(i=0; i<n; i++)
{ printf("\n请输入第%d个学生的学号:",i+1); scanf("\n%s",&stu[i].no);
printf("\n请输入第%d个学生的姓名:",i+1); scanf("%s",&stu[i].name); printf("\n请输入第%d
个学生的性别:",i+1); scanf("%s",&stu[i].sex); printf("\n请输入第%d 个学生的年龄:",i+1);
scanf("%d",&stu[i].age); printf("\n请输入第%d 个学生的C语言成绩:",i+1);
scanf("%d",&stu[i].C); printf("\n请输入第%d 个学生的高等数学成绩:",i+1);
scanf("%d",&stu[i].M); printf("\n请输入第%d 个学生的大学英语成绩:",i+1);
scanf("%d",&stu[i].E); sort(); //调用按学号排序函数 //写入文件 fprintf(fp,"%s %16s %10s %10d
%10.1f %10.1f
%10.1f\n",stu[i].no,stu[i].name,stu[i].sex,stu[i].age,stu[i].C,stu[i].M,stu[i].E);
} printf("\n添加成功!!!\n"); fclose(fp); } //按学号删除信息 void del() { int j=0; FILE *
fp; if((fp=fopen("student.txt","r"))==NULL) return ; while(fscanf(fp,"%s %s %s
%d %f %f %f
",&stu[j].no,&stu[j].name,&stu[j].sex,&stu[j].age,&stu[j].C,&stu[j].M,&stu[j].E)==7)
{ j++; } n=j; int i,flag=0; char s1[LEN+1]; printf("请输入要删除学生的学号:\n");
scanf("%s",s1); for(i=0; i<n; i++) { if(strcmp(stu[i].no,s1)==0)
//比较输入的学号和记录的学号一致 { flag=1; for(j=i; j<n-1; j++) { stu[j]=stu[j+1];
//后面的学生记录向前移动 } } } if(flag==0) //比较输入的学号和记录的学号不一致 printf("该学号不存在!\n");
if(flag==1) //判断flag的值为1,则成功删除 { n--; //删除成功后,学生人数-1 fileWrite(); fclose(fp);
printf("删除成功,显示结果请选择菜单\n"); } } //显示当前信息 void display() { int i=0; FILE * fp;
if((fp=fopen("student.txt","r"))==NULL) printf("文件为空!\n"); while(fscanf(fp,"%s
%s %s %d %f %f
%f",stu[i].no,stu[i].name,stu[i].sex,&stu[i].age,&stu[i].C,&stu[i].M,&stu[i].E)==7)
{ i++; } n=i; //记录文件中数据的行数 printf("学生学号 学生姓名 年龄 性别 C语言成绩 高等数学 大学英语成绩\n");
printf("--------------------------------------------------------------------\n");
for(i=0;i<n;i++) //依次输出学生信息 { printf("%s %16s %10s %10d %10.1f %10.1f
%10.1f\n",stu[i].no,stu[i].name,stu[i].sex,stu[i].age,stu[i].C,stu[i].M,stu[i].E);
} fclose(fp); } //保存当前学生信息 void fileWrite() { FILE *fp; int i;
if((fp=fopen("student.txt","w"))==NULL) printf("文件为空!\n"); for(i=0; i<n; i++) {
fprintf(fp,"%s %16s %10s %10d %10.1f %10.1f
%10.1f\n",stu[i].no,stu[i].name,stu[i].sex,stu[i].age,stu[i].C,stu[i].M,stu[i].E);
} fclose(fp); printf("保存成功!!!"); } //界面 void menu() { int num; printf(" \n\n
\n\n"); printf(" * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n");
printf(" * 学生信息管理系统 *\n"); printf(" * *\n"); printf(" * * * * * * * *系统功能菜单* *
* * * * * *\n"); printf(" * -------------------------------------------- *\n");
printf(" * *\n"); printf(" * 0.系统帮助及说明 | 1.刷新学生信息 *\n"); printf(" * *\n");
printf(" * 2.查询学生信息 | 3.修改学生信息 *\n"); printf(" * *\n"); printf(" * 4.增加学生信息 |
5.按学号删除信息 *\n"); printf(" * *\n"); printf(" * 6.显示当前信息 | 7.保存当前学生信息 *\n");
printf(" * *\n"); printf(" * 8.退出系统 *\n"); printf(" * * * * * * * * * * * * * *
* * * * * * * * * * * * * * *\n"); printf("- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - \n"); printf("请选择菜单编号:"); scanf("%d",&num); switch(num) {
case 0: help(); break; case 1: update(); break; case 2: seek(); break; case 3:
modify(); break; case 4: insert(); break; case 5: del(); break; case 6:
display(); break; case 7: fileWrite(); break; case 8: k=0; break; default:
printf("请在0-8之间选择\n"); } } //主函数 int main() { while(k) { menu(); }
system("pause"); return 0; }
●经验归纳
●●遇到的问题
程序无法读取文件信息:对文件的概念不清楚,文件的读取中各个数据之间不能用逗号隔开
●●算法优化
<1>将主函数写到子函数后面,删去函数声明
<2>利用结构体,使学生信息更加结构化
<3>新增按学号排序函数,用户在增加了学生信息后,调用该函数,将文件中学生信息按学号排序好
<4>优化删除学生信息函数,直接将后面的学生记录向前移动
<5>将每个涉及文件的子函数都加入了文件读取功能,目的是进行相应操作时不必每次都要先执行刷新函数
<6>优化修改学生信息函数,每次修改完都调用保存函数,实现自动保存
●●心得体会
学生信息管理系统是我们在学习C语言时的典例,但是我感觉在文件读取方面基础还是比较薄弱,一些基础性的知识点还是不能记住,所以以后要多多练习与读取文件有关的习题。