作者:A.y.
日期:2019/4/2
运行环境:Visual C++ 6.0
一、实验内容
对已经给出的学生信息管理系统,要求完成以下基本任务:
1.改写程序为良好程序风格(文档注释,函数注释,语句注释)。
2.将功能补充完全(基于文件处理,完成刷新和保存功能)。
3.将学生信息改为更好的数据组织,而非离散形式(结构体)。
提高要求:
可将程序中的不足(如数据验证)等根据自己的能力与理解完成。
二、代码优化以及补充
(1).补充readin()函数:
将新增的学生信息存入文件data.txt中;
(2).补充datain()函数:
将文件中的学生信息读出并存入结构体数组变量中;
(3).补充newMessage()函数:
将修改过的学生信息存入文件data.txt并将被修改的信息删除进行更新;
(4).新增学生信息判断语句
在插入函数insert()中判断输入学生人数是否正确(即输入人数是否大于0),并且判断输入学生学号是否已存在,若存在,则重新输入,否则继续输入该学生其他信息;
(5).在执行了插入函数insert()之后,执行sort()函数对学生信息按学号进行排列;
(6).将离散型变量用结构体表示
修改前 修改后
char *code[N]; char *name[N];
int age[N];
char sex[N]; float score[N][3];
struct Student
{
char code[length];
char name[length];
int age;
char sex;
float score[3];
}stu[N];
三、算法设计流程图
四、代码实现
#include<stdio.h> /*I/O函数*/
#include<stdlib.h> /*其它说明*/
#include<string.h> /*字符串函数*/
#define N 50 /* 最大学生人数,实际请更改*/
#define length 20 /*姓名和学号的最大长度*/
struct Student
{
char code[length]; /* 学号*/
char name[length]; /* 姓名*/
int age; /* 年龄*/
char sex; /* 性别*/
float score[3]; /* 3门课程成绩*/
}stu[N];
int k=1,n=0, m=0,f; /*k表示程序继续进行的标志,n代表当前记录的学生人数,f表示*/
bool symbol=false; /*symbol表示进行每项操作后需要按任意键执行下一步操作*/
void seek();
void modify();
void insert();
void del();
void display();
void menu();
void datain();
void newMessage();
int main()
{
datain();
while(k)
{
menu();
}
return 0;
}
void help() /*菜单命令*/
{
printf("\n0.欢迎使用系统帮助!\n");
printf("\n1.初次进入系统后,请先选择增加学生信息;\n");
printf("\n2.按照菜单提示键入数字代号;\n");
printf("\n3.增加学生信息后,切记保存;\n");
printf("\n4.进行完每次操作后请刷新信息;\n");
printf("\n5.谢谢您的使用!\n");
}
void seek() /*查找*/
{
int i,item,flag;
char s1[21]; /* 以姓名和学号最长长度+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++)
if(strcmp(stu[i].code,s1)==0)
{
flag=1;
printf("学生学号 学生姓名 年龄 性别 C语言成绩 高等数学 大学英语成绩\n");
printf("--------------------------------------------------------------------\n");
printf("%6s %7s %6d %6c %9.1f %10.1f %10.1f\n",stu[i].code,stu[i].name,stu[i].age,stu[i].sex,stu[i].score[0],stu[i].score[1],stu[i].score[2]);
}
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("%6s %7s %6d %6c %9.1f %10.1f %10.1f\n",stu[i].code,stu[i].name,stu[i].age,stu[i].sex,stu[i].score[0],stu[i].score[1],stu[i].score[2]);
}
if(0==flag)
printf("该姓名不存在!\n"); break;
case 3:return;
default:printf("请在1-3之间选择\n");
}
}
}
void modify() /*修改信息*/
{
int i,item,num,age1;
char sex1,s1[length+1],s2[length+1]; /* 以姓名和学号最长长度+1为准*/
float score1;
printf("请输入要要修改的学生的学号:\n");
scanf("%s",s1);
for(i=0;i<n;i++)
if(strcmp(stu[i].code,s1)==0) /*比较字符串是否相等*/
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("请输入新的姓名:\n");
scanf("%s",s2);
strcpy(stu[num].name,s2);
break;
case 2:
printf("请输入新的年龄:\n");
scanf("%d",&age1);
stu[num].age=age1;
break;
case 3:
printf("请输入新的性别:\n");
scanf(" %c",&sex1);
stu[num].sex=sex1;
break;
case 4:
printf("请输入新的C语言成绩:\n");
scanf("%f",&score1);
stu[num].score[0]=score1; break;
case 5:
printf("请输入新的高等数学成绩:\n");
scanf("%f",&score1);
stu[num].score[1]=score1; break;
case 6:
printf("请输入新的大学英语成绩:\n");
scanf("%f",&score1);
stu[num].score[2]=score1; break;
case 7: return;
default:printf("请在1-7之间选择\n");
}
}
}
void sort()/*按学号排序*/
{
int i,j,k,s;
char temp[length+1],ctemp;
float ftemp;
for(i=0;i<n-1;i++)
{
for(j=n-1;j>i;j--)
if(strcmp(stu[j-1].code,stu[j].code)>0)
{
strcpy(temp,stu[j-1].code);
strcpy(stu[j-1].code,stu[j].code);
strcpy(stu[j].code,temp);
strcpy(temp,stu[j-1].name);
strcpy(stu[j-1].name,stu[j].name);
strcpy(stu[j].name,temp);
ctemp=stu[j-1].sex;
stu[j-1].sex=stu[j].sex;
stu[j].sex=ctemp;
s=stu[j-1].age;
stu[j-1].age=stu[j].age;
stu[j].age=s;
for(k=0;k<3;k++)
{
ftemp=stu[j-1].score[k];
stu[j-1].score[k]=stu[j].score[k];
stu[j].score[k]=ftemp;
}
}
}
}
void insert() /*插入函数*/
{
int j=n;
bool size;
printf("请输入待增加的学生数:\n");
scanf("%d",&m);
if(m<0)
{
printf("增加人数错误!");
return;
}
do
{
size=true;
printf("请输入第%d 个学生的学号:\n",j-n+1);
while(size)
{
size=false;
scanf("%s",stu[j].code);
for(int i=0;i<j;i++)
if(strcmp(stu[i].code,stu[j].code)==0)
{
printf("学号重复,请重新输入!\n");
size=true;
break;
}
}
printf("请输入第%d 个学生的姓名:\n",j-n+1);
scanf("%s",stu[j].name);
printf("请输入第%d 个学生的年龄:\n",j-n+1);
scanf("%d",&stu[j].age);
printf("请输入第%d 个学生的性别:\n",j-n+1);
scanf(" %c",&stu[j].sex);
printf("请输入第%d 个学生的C语言成绩\n",j-n+1);
scanf("%f",&stu[j].score[0]);
printf("请输入第%d 个学生的高等数学成绩:\n",j-n+1);
scanf("%f",&stu[j].score[1]);
printf("请输入第%d 个学生的大学英语成绩:\n",j-n+1);
scanf("%f",&stu[j].score[2]);
j++;
}while(j<n+m);
n+=m;
printf("信息增加完毕!\n\n");
sort();
}
void del() /*删除指定学号信息*/
{
int i,j,flag=0;
char s1[length+1];
printf("请输入要删除学生的学号:\n");
scanf("%s",s1);
for(i=0;i<n;i++)
if(strcmp(stu[i].code,s1)==0)
{
flag=1;
for(j=i;j<n-1;j++)
stu[j]=stu[j+1];
}
if(flag==0)
printf("该学号不存在!\n");
if(flag==1)
{
printf("删除成功,显示结果请选择菜单\n");
n--;
}
}
void datain() /*将文件data.txt中保存的学生信息导出*/
{
FILE *fp1;
fp1=fopen("data.txt","r");
while(fscanf(fp1,"%s %s %d %c %f %f %f\n",&stu[n].code,&stu[n].name,&stu[n].age,&stu[n].sex,&stu[n].score[0],&stu[n].score[1],&stu[n].score[2])==7)
{
n++;
}
f=n;
fclose(fp1);
}
void readin() /*将学生信息存入文件data.txt*/
{
FILE *fp;
fp=fopen("data.txt","at");
for(int i=f;i<n;i++)
fprintf(fp,"%7s %7s %6d %6c %9.1f %10.1f %10.1f\n",stu[i].code,stu[i].name,stu[i].age,stu[i].sex,stu[i].score[0],stu[i].score[1],stu[i].score[2]);
f=n;
fclose(fp);
printf("\n\n\t保存成功!");
}
void newMessage() /*更新信息*/
{
FILE *fp1;
fp1=fopen("data.txt","w");
f=0;
readin();
fclose(fp1);
}
void display() /*显示学生信息*/
{
int i;
printf("共有%d位学生的信息:\n",n);
if(0!=n)
{
printf("学生学号 学生姓名 年龄 性别 C语言成绩 高等数学 大学英语成绩\n");
printf("--------------------------------------------------------------------\n");
for(i=0;i<n;i++)
{
printf("%7s %7s %6d %6c %9.1f %10.1f %10.1f\n",stu[i].code,stu[i].name,stu[i].age,stu[i].sex,stu[i].score[0],stu[i].score[1],stu[i].score[2]);
}
}
}
void menu()/* 界面*/
{
int num;
if(symbol)
{
printf("\n");
system("pause");
}
symbol=true;
system("cls");
printf(" \n \n");
printf(" **********************************************************\n\n");
printf(" * 学生信息管理系统 *\n \n");
printf(" **********************************************************\n\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:
system("cls");
help();
break;
case 1:
system("cls");
newMessage();
break;
case 2:
system("cls");
seek();
break;
case 3:
system("cls");
modify();
break;
case 4:
system("cls");
insert();
sort();
break;
case 5:
system("cls");
del();
break;
case 6:
system("cls");
display();
break;
case 7:
system("cls");
readin();
break;
case 8:
k=0;
break;
default:printf("请在0-8之间选择\n");
}
}
五、调试截图
(1).在将学生信息存入文件的时候遇到了一个问题,在每次存入新的学生信息时都会将之前存入过的学生信息再次存入文件
先存入一个学生信息:
再存入一个学生信息:
仔细检查读入文件函数readin()之后发现每次存学生信息都是从第一个而不是从之前已存完的地方开始
该循环应从上次结束的地方开始,修改之后为
(2).在datain()函数中,将学生信息从文件中的导出时,忘记加取地址符 &
(3).在调试时发现若对已存入文件的学生信息进行修改,在文件里的学生信息不会改变
修改过后文件中的学生信息:
考虑到这个问题,修改时需要把旧信息删掉,再把新信息存入,增加了一个newMessage()函数。
六、测试及运行截图
运行之前已保存到data.txt文件中的数据:
菜单界面:
操作0:
操作2:
操作3:
操作4:
操作5:
操作6:
进行完上述操作后文件data.txt中的数据:
七、个人总结
在这次学生信息管理系统的优化实验中,我对从文件中读取数据的操作更加的熟练的一些,查阅资料发现要删除文件中的数据需要有标识符,因为在修改学生信息的时候,我用的方法是新建一个data.txt文件,然后再将修改过的学生信息存入文件中。还有就是在从文件中独处数据时,需要在fscnf()函数中加入取地址符&。