目录
题目描述
学生信息管理系统用来管理学生信息,学生信息包括:学号,姓名,年龄,性别,出生年月,地址,电话,E-mail等。试设计一个学生信息管理系统,其至少应该提供以下功能:
1) 定义一个菜单函数,进入系统界面;
2) 输入本组所有学生信息(学生信息用文件info.txt保存);
3)按学号或姓名查询学生信息;
4)添加其它组某个学生到该组指定姓名或学号的学生后面;
5)删除学生记录;
6)修改指定姓名或学号的学生的电话号码并可存盘;
7)退出系统。
分析需求,首先考虑如何存储学生的信息,由于是基于结构体实现,因此本例中我们使用结构体来实现信息的存储,相关代码如下:
typedef struct date{
int y,m,d;//年 月 日
}Date;
typedef struct student{
double ID;//学号
char Name[20];//姓名
int Age;//年龄
char Sex[5];//性别
Date Birthday;//出生日期
char Address[120];//地址
double Phone;//手机号码
double QQ;//QQ号码
char Email[50];//邮箱
}Stu;
再将描述中的各项要求剥离出来,抽象成各类函数如下:
①主菜单函数
②录入信息函数
③查询信息函数
④添加信息函数
⑤删除信息函数
⑥修改信息函数
⑦退出系统函数
在此基础上,我又修改或添加了部分函数,具体如下:
1)增加一个显示信息函数,用来显示录入后的信息,并且有排序显示功能。
2)添加信息函数中增加一个直接追加信息的功能,也即可以直接在文件尾追加新的学生信息。
3)增加一个清空信息函数,当用户想清空所有信息时可以调用此函数一键清空所有已录入信息。
4)增加一个使用说明函数,帮助第一次使用本系统的用户学习使用本管理系统。
源码详解
由于篇幅限制,这里只讲解主菜单函数,录入信息函数,删除信息函数,修改信息函数。
话不多说,直接上代码:
主菜单函数
int color(int c)//修改字符颜色
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);
return 0;
}
void gotoxy(short x, short y)//跳到X,Y坐标并修改接下来输出的字符的颜色
{
COORD p = { x,y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), p);
color(2);
}
void menu()//主菜单函数
{
system("cls");
color(6);
printf("\t\t 学生信息管理系统 \n");
printf("\t\t----------------------------------------------------------\n");
color(2);
printf("\t\t 1.录入学生信息 欢迎使用学生信 \n");
printf("\t\t 2.显示学生信息 息管理系统,输 \n");
printf("\t\t 3.查询学生信息 入相应数字进入 \n");
printf("\t\t 4.添加学生信息 功能,输入8查 \n");
printf("\t\t 5.删除学生信息 查看使用说明。 \n");
printf("\t\t 6.修改学生信息 \n");
printf("\t\t 7.清空学生信息 \n");
printf("\t\t 0.退出管理系统 \n");
color(6);
printf("\t\t----------------------------------------------------------\n");
gotoxy(49, 8);//将光标跳转到该位置方便接下来的输出
}
函数功能已经在注释中解释,需要注意的是,color函数和gotoxy函数调用了Windows的API,因此在包含头文件时要加上#include<Windows.h>,主菜单是用户第一眼看到的界面,因此设计成什么样更好看因人而异,可以自行发挥。
录入信息函数
void createinfo()//创建文件函数
{
if((fpFile=fopen("info.txt","a+"))==NULL)
{
printf("创建文件失败!\n");
exit(0);
}
fclose(fpFile);
}
void writeinfo()//文件写入函数
{
void createinfo();//先创建文件
if((fpFile=fopen("info.txt","a+"))==NULL)
{
printf("创建文件失败!\n");
exit(0);
}
for(int l=0;l<5;l++){//写入五名小组成员的信息
fprintf(fpFile,"%s ",MGroup[l].Name);
fprintf(fpFile,"%.0lf ",MGroup[l].ID);
fprintf(fpFile,"%d ",MGroup[l].Age);
fprintf(fpFile,"%s ",MGroup[l].Sex);
fprintf(fpFile,"%d %d %d ",MGroup[l].Birthday.y,MGroup[l].Birthday.m,MGroup[l].Birthday.d);
fprintf(fpFile,"%s ",MGroup[l].Address);
fprintf(fpFile,"%.0lf ",MGroup[l].Phone);
fprintf(fpFile,"%.0lf ",MGroup[l].QQ);
fprintf(fpFile,"%s\n",MGroup[l].Email);
}
fclose(fpFile);
printf("写入信息成功!\n");
system("pause");
}
void saveinfo()//录入学生信息函数
{
system("cls");
for(int i=0;i<5;i++){//先将数据赋给结构体变量,而后再写入
printf("开始录入信息,本组一共5名同学,请先输入第%d名同学的姓名:\n",i+1);
scanf("%s",MGroup[i].Name);
printf("请输入第%d名同学的学号:\n",i+1);
scanf("%lf",&MGroup[i].ID);
printf("请输入第%d名同学的年龄:\n",i+1);
scanf("%d",&MGroup[i].Age);
printf("请输入第%d名同学的性别:\n",i+1);
scanf("%s",&MGroup[i].Sex);
printf("请输入第%d名同学的出生日期:\n",i+1);
scanf("%d %d %d",&MGroup[i].Birthday.y,&MGroup[i].Birthday.m,&MGroup[i].Birthday.d);
printf("请输入第%d名同学的地址:\n",i+1);
scanf("%s",&MGroup[i].Address);
printf("请输入第%d名同学的电话:\n",i+1);
scanf("%lf",&MGroup[i].Phone);
printf("请输入第%d名同学的QQ号码:\n",i+1);
scanf("%lf",&MGroup[i].QQ);
printf("请输入第%d名同学的邮箱:\n",i+1);
scanf("%s",&MGroup[i].Email);
system("cls");
}
writeinfo();//调用文件写入函数写入数据
}
因创建文件和写入信息的功能后面会多次使用,因此这里先把这两个功能写成了函数方便后面的调用。这里录入功能的实现就是简单的从用户的键盘读取数据存储到结构体中,再把结构体中的数据写入到文件中,使用fprintf是为了更好地控制格式。
删除信息函数
void delinfo()//删除学生信息函数
{
int target=-1;//存储要删除的学生信息结构体变量对应的下标
while(target==-1){//如果找不到对应学生,重复输入过程
system("cls");
printf("请输入要删除的同学的姓名\n");
char name[20];
scanf("%s",name);
for(int i=0;i<GroupSize;i++){//在结构体数组中查找是否有对应的学生
if(strcmp(MGroup[i].Name,name)==0)
{
target=i;
break;
}
}
}
if((fpFile=fopen("info.txt","r+"))==NULL)
{
printf("打开文件失败!\n");
exit(0);
}
int cnt=-1;
for(int l=0;feof(fpFile)==0;l++){//读取文件数据到结构体数组中并获取文件长度
fscanf(fpFile,"%s %lf %d %s",MGroup[l].Name,&MGroup[l].ID,&MGroup[l].Age,&MGroup[l].Sex);
fscanf(fpFile,"%d %d %d",&MGroup[l].Birthday.y,&MGroup[l].Birthday.m,&MGroup[l].Birthday.d);
fscanf(fpFile,"%s %lf %lf",&MGroup[l].Address,&MGroup[l].Phone,&MGroup[l].QQ);
fscanf(fpFile,"%s",&MGroup[l].Email);
cnt++;
}
fclose(fpFile);
fpFile=fopen("info.txt","w+");//清空数据
for(int i=target;i<cnt;i++){//让后面的数据覆盖掉已经删除的数据
MGroup[i]=MGroup[i+1];
}
for(int l=0;l<cnt-1;l++){//重新写入数据
fprintf(fpFile,"%s ",MGroup[l].Name);
fprintf(fpFile,"%.0lf ",MGroup[l].ID);
fprintf(fpFile,"%d ",MGroup[l].Age);
fprintf(fpFile,"%s ",MGroup[l].Sex);
fprintf(fpFile,"%d %d %d ",MGroup[l].Birthday.y,MGroup[l].Birthday.m,MGroup[l].Birthday.d);
fprintf(fpFile,"%s ",MGroup[l].Address);
fprintf(fpFile,"%.0lf ",MGroup[l].Phone);
fprintf(fpFile,"%.0lf ",MGroup[l].QQ);
fprintf(fpFile,"%s\n",MGroup[l].Email);
}
fclose(fpFile);
printf("删除成功!\n");
system("pause");
}
这里是在结构体中查找数据,因为题目并未要求先读取文件中的数据,也就是实现读取文件数据的操作,不过也可以查询文件中的数据,只要先读取一遍文件(在查询信息函数中有读取功能),将其中的数据写入到结构体中即可。这里需要先获取文件长度的原因是数据,也即小组成员是不定的,可能会有添加和删除,因此需要先获取“文件长度”。因为C中没有指定行删除操作的函数,所以这里使用了一个取巧的方法,先把结构体中存储的数据修改,再把文件里的数据清空,最后把修改后的结构体数据写入文件中,即可实现删除信息的功能。
修改信息函数
void changeinfo()//修改指定学生电话号码函数
{
int target=-1;//存储要修改的学生的结构体变量对应的下标
while(target==-1){//如果找不到对应学生,重复输入过程
system("cls");
printf("请输入要修改的同学的姓名\n");
char name[20];
scanf("%s",name);
for(int i=0;i<GroupSize;i++){//在结构体数组中查找是否有对应的学生
if(strcmp(MGroup[i].Name,name)==0)
{
target=i;
break;
}
}
}
printf("请输入修改后的电话号码:\n");
double changephone;
scanf("%lf",&changephone);
if((fpFile=fopen("info.txt","r+"))==NULL)
{
printf("打开文件失败!\n");
exit(0);
}
int cnt=-1;
for(int l=0;feof(fpFile)==0;l++){//读取文件数据并获取文件长度
fscanf(fpFile,"%s %lf %d %s",MGroup[l].Name,&MGroup[l].ID,&MGroup[l].Age,&MGroup[l].Sex);
fscanf(fpFile,"%d %d %d",&MGroup[l].Birthday.y,&MGroup[l].Birthday.m,&MGroup[l].Birthday.d);
fscanf(fpFile,"%s %lf %lf",&MGroup[l].Address,&MGroup[l].Phone,&MGroup[l].QQ);
fscanf(fpFile,"%s",&MGroup[l].Email);
cnt++;
}
fclose(fpFile);
fpFile=fopen("info.txt","w+");//先清空数据
MGroup[target].Phone=changephone;
for(int l=0;l<cnt;l++){//重新写入修改后的数据
fprintf(fpFile,"%s ",MGroup[l].Name);
fprintf(fpFile,"%.0lf ",MGroup[l].ID);
fprintf(fpFile,"%d ",MGroup[l].Age);
fprintf(fpFile,"%s ",MGroup[l].Sex);
fprintf(fpFile,"%d %d %d ",MGroup[l].Birthday.y,MGroup[l].Birthday.m,MGroup[l].Birthday.d);
fprintf(fpFile,"%s ",MGroup[l].Address);
fprintf(fpFile,"%.0lf ",MGroup[l].Phone);
fprintf(fpFile,"%.0lf ",MGroup[l].QQ);
fprintf(fpFile,"%s\n",MGroup[l].Email);
}
fclose(fpFile);
printf("修改成功!\n");
system("pause");
}
功能实现与删除信息函数大同小异,也是先在结构体中查找数据然后修改结构体,然后清空文件中的数据最后把修改后的结构体的数据存入文件中,不过这里题目中只要求修改电话号码,因此只做了修改电话号码的功能,如果要修改整个信息或者单独修改其他信息,简单改一下源码即可。
完整源码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<Windows.h>
#include<conio.h>
#define GroupSize 10//小组大小,定义为10是因为之后可能还要添加或删除数据
FILE *fpFile;//文件指针,方便之后使用
void menu();//主菜单函数
void exitsystem();//退出系统函数
void saveinfo();//录入信息函数
void showinfo();//显示信息函数
void findinfo();//查询信息函数
void addinfo();//添加信息函数
void delinfo();//删除信息函数
void changeinfo();//修改信息函数
void deleteall();//清空信息函数
void help();//使用说明函数
typedef struct date{
int y,m,d;//年 月 日
}Date;
typedef struct student{
double ID;//学号
char Name[20];//姓名
int Age;//年龄
char Sex[5];//性别
Date Birthday;//出生日期
char Address[120];//地址
double Phone;//手机号码
double QQ;//QQ号码
char Email[50];//邮箱
}Stu;
Stu MGroup[GroupSize];
int main()
{
int choice;//存储用户选择
for(;;)
{
menu();
printf("请输入:");
scanf("%d", &choice);
switch (choice) {//用户输入对应的数字则跳转到对应的函数
case 0:exitsystem(); break;
case 1:saveinfo();break;
case 2:showinfo();break;
case 3:findinfo();break;
case 4:addinfo();break;
case 5:delinfo();break;
case 6:changeinfo();break;
case 7:deleteall();break;
case 8:help();break;
default:system("cls"); break;//如果用户输入其他非法数据,清屏并重新显示主菜单
}
}
return 0;
}
int color(int c)//修改字符颜色
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);
return 0;
}
void gotoxy(short x, short y)//跳到X,Y坐标并修改接下来输出的字符的颜色
{
COORD p = { x,y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), p);
color(2);
}
void menu()//主菜单函数
{
system("cls");
color(6);
printf("\t\t 学生信息管理系统 \n");
printf("\t\t----------------------------------------------------------\n");
color(2);
printf("\t\t 1.录入学生信息 欢迎使用学生信 \n");
printf("\t\t 2.显示学生信息 息管理系统,输 \n");
printf("\t\t 3.查询学生信息 入相应数字进入 \n");
printf("\t\t 4.添加学生信息 功能,输入8查 \n");
printf("\t\t 5.删除学生信息 查看使用说明。 \n");
printf("\t\t 6.修改学生信息 \n");
printf("\t\t 7.清空学生信息 \n");
printf("\t\t 0.退出管理系统 \n");
color(6);
printf("\t\t----------------------------------------------------------\n");
gotoxy(49, 8);//将光标跳转到该位置方便接下来的输出
}
void createinfo()//创建文件函数
{
if((fpFile=fopen("info.txt","a+"))==NULL)
{
printf("创建文件失败!\n");
exit(0);
}
fclose(fpFile);
}
void writeinfo()//文件写入函数
{
void createinfo();//先创建文件
if((fpFile=fopen("info.txt","a+"))==NULL)
{
printf("创建文件失败!\n");
exit(0);
}
for(int l=0;l<5;l++){//写入五名小组成员的信息
fprintf(fpFile,"%s ",MGroup[l].Name);
fprintf(fpFile,"%.0lf ",MGroup[l].ID);
fprintf(fpFile,"%d ",MGroup[l].Age);
fprintf(fpFile,"%s ",MGroup[l].Sex);
fprintf(fpFile,"%d %d %d ",MGroup[l].Birthday.y,MGroup[l].Birthday.m,MGroup[l].Birthday.d);
fprintf(fpFile,"%s ",MGroup[l].Address);
fprintf(fpFile,"%.0lf ",MGroup[l].Phone);
fprintf(fpFile,"%.0lf ",MGroup[l].QQ);
fprintf(fpFile,"%s\n",MGroup[l].Email);
}
fclose(fpFile);
printf("写入信息成功!\n");
system("pause");
}
void upsortinfo(int max)//升序排序函数
{
for(int i=0;i<max-1;i++){//选择排序
int flag=i;
for(int j=i+1;j<max;j++){
if(MGroup[flag].ID>MGroup[j].ID){
flag=j;
}
}
Stu temp =MGroup[i];//相同结构体之间可直接赋值
MGroup[i]=MGroup[flag];
MGroup[flag]=temp;
}
}
void downsortinfo(int max)//降序排列函数
{
for(int i=0;i<max-1;i++){//选择排序
int flag=i;
for(int j=i+1;j<max;j++){
if(MGroup[flag].ID<MGroup[j].ID){
flag=j;
}
}
Stu temp =MGroup[i];//相同结构体之间可直接赋值
MGroup[i]=MGroup[flag];
MGroup[flag]=temp;
}
}
void saveinfo()//录入学生信息函数
{
system("cls");
for(int i=0;i<5;i++){//先将数据赋给结构体变量,而后再写入
printf("开始录入信息,本组一共5名同学,请先输入第%d名同学的姓名:\n",i+1);
scanf("%s",MGroup[i].Name);
printf("请输入第%d名同学的学号:\n",i+1);
scanf("%lf",&MGroup[i].ID);
printf("请输入第%d名同学的年龄:\n",i+1);
scanf("%d",&MGroup[i].Age);
printf("请输入第%d名同学的性别:\n",i+1);
scanf("%s",&MGroup[i].Sex);
printf("请输入第%d名同学的出生日期:\n",i+1);
scanf("%d %d %d",&MGroup[i].Birthday.y,&MGroup[i].Birthday.m,&MGroup[i].Birthday.d);
printf("请输入第%d名同学的地址:\n",i+1);
scanf("%s",&MGroup[i].Address);
printf("请输入第%d名同学的电话:\n",i+1);
scanf("%lf",&MGroup[i].Phone);
printf("请输入第%d名同学的QQ号码:\n",i+1);
scanf("%lf",&MGroup[i].QQ);
printf("请输入第%d名同学的邮箱:\n",i+1);
scanf("%s",&MGroup[i].Email);
system("cls");
}
writeinfo();//调用文件写入函数写入数据
}
void showinfo()//显示学生信息函数
{
system("cls");
if((fpFile=fopen("info.txt","r+"))==NULL)
{
printf("文件未创建或为空!即将退出程序\n");
system("pause");//暂停程序,给用户一个反应时间
exit(0);
}
if(feof(fpFile)==1)
{
printf("文件未创建或为空!即将退出程序\n");
system("pause");//暂停程序,给用户一个反应时间
exit(0);
}
int sortway;//存储用户选择方式
printf("按学号升序或降序排列显示学生信息?\n");
printf("1.按升序排列显示学生信息\n");
printf("2.按降序排列显示学生信息\n");
printf("3.不进行排序直接显示学生信息\n");
printf("请输入:");
scanf("%d",&sortway);
int cnt=0;
for(int l=0;feof(fpFile)==0;l++){//读取文件数据并获取文件长度
fscanf(fpFile,"%s %lf %d %s",MGroup[l].Name,&MGroup[l].ID,&MGroup[l].Age,&MGroup[l].Sex);
fscanf(fpFile,"%d %d %d",&MGroup[l].Birthday.y,&MGroup[l].Birthday.m,&MGroup[l].Birthday.d);
fscanf(fpFile,"%s %lf %lf",&MGroup[l].Address,&MGroup[l].Phone,&MGroup[l].QQ);
fscanf(fpFile,"%s",&MGroup[l].Email);
cnt++;
}
if(sortway==1)upsortinfo(cnt-1);//如果用户输入1,按升序排列数据
if(sortway==2)downsortinfo(cnt-1);//如果用户输入2,按降序排列数据
system("cls");//将前面输入的文字信息清屏,方便显示数据
for(int i=0;i<cnt-1;i++){
printf("%s ",MGroup[i].Name);
printf("%.0lf ",MGroup[i].ID);
printf("%d ",MGroup[i].Age);
printf("%s ",MGroup[i].Sex);
printf("%d %d %d ",MGroup[i].Birthday.y,MGroup[i].Birthday.m,MGroup[i].Birthday.d);
printf("%s ",MGroup[i].Address);
printf("%.0lf ",MGroup[i].Phone);
printf("%.0lf ",MGroup[i].QQ);
printf("%s\n",MGroup[i].Email);
}
system("pause");//暂停程序,方便用户查看数据
fclose(fpFile);
}
void findinfo()//查询学生信息函数
{
system("cls");
printf("按学号查询还是按姓名查询?\n");
printf("1.按学号查询\n");
printf("2.按姓名查询\n");
int target=-1;//存储查询目标的下标
int findway;//存储用户选择
scanf("%d",&findway);
if(findway==1)//如果用户输入1,按学号查询
{
printf("请输入学号:");
double ID;
scanf("%lf",&ID);
for(int i=0;i<GroupSize;i++){//查找符合输入数据的学生信息
if(MGroup[i].ID==ID){
target=i;
break;
}
}
if(target!=-1)//如果查询成功,输出数据
{
printf("%s ",MGroup[target].Name);
printf("%.0lf ",MGroup[target].ID);
printf("%d ",MGroup[target].Age);
printf("%s ",MGroup[target].Sex);
printf("%d %d %d ",MGroup[target].Birthday.y,MGroup[target].Birthday.m,MGroup[target].Birthday.d);
printf("%s ",MGroup[target].Address);
printf("%.0lf ",MGroup[target].Phone);
printf("%.0lf ",MGroup[target].QQ);
printf("%s\n",MGroup[target].Email);
system("pause");
}
else
{
printf("未找到此学生!请检查输入是否正确!\n");
system("pause");
findinfo();//查询失败则重新查询
}
}
if(findway==2)//如果用户输入2,按姓名查询
{
printf("请输入姓名:");
char name[20];
scanf("%s",name);
for(int i=0;i<GroupSize;i++){
if(strcmp(MGroup[i].Name,name)==0){//查找符合输入数据的学生信息
target=i;
break;
}
}
if(target!=-1)//如果查询成功,输出数据
{
printf("%s ",MGroup[target].Name);
printf("%.0lf ",MGroup[target].ID);
printf("%d ",MGroup[target].Age);
printf("%s ",MGroup[target].Sex);
printf("%d %d %d ",MGroup[target].Birthday.y,MGroup[target].Birthday.m,MGroup[target].Birthday.d);
printf("%s ",MGroup[target].Address);
printf("%.0lf ",MGroup[target].Phone);
printf("%.0lf ",MGroup[target].QQ);
printf("%s\n",MGroup[target].Email);
system("pause");
}
else
{
printf("未找到此学生!请检查输入是否正确!\n");
system("pause");
findinfo();//查询失败则重新查询
}
}
}
void addinfo()//添加学生信息函数
{
system("cls");
printf("你想要追加信息还是在指定学生后添加信息?\n");
printf("1.直接追加信息\n");
printf("2.在指定学生后添加信息\n");
int flag_add;//存储用户选择
scanf("%d",&flag_add);
if(flag_add==1)//如果用户输入1,直接在文件末尾追加信息
{
system("cls");
if((fpFile=fopen("info.txt","at+"))==NULL)//以读写方式打开文本文件,在文件末尾追加数据
{
printf("打开文件失败!\n");
exit(0);
}
int cnt=0;
for(int l=0;feof(fpFile)==0;l++){//先读取文件数据并获取文件长度
fscanf(fpFile,"%s %lf %d %s",MGroup[l].Name,&MGroup[l].ID,&MGroup[l].Age,&MGroup[l].Sex);
fscanf(fpFile,"%d %d %d",&MGroup[l].Birthday.y,&MGroup[l].Birthday.m,&MGroup[l].Birthday.d);
fscanf(fpFile,"%s %lf %lf",&MGroup[l].Address,&MGroup[l].Phone,&MGroup[l].QQ);
fscanf(fpFile,"%s",&MGroup[l].Email);
cnt++;
}
printf("开始添加信息,请输入此同学的姓名:\n");//读取要添加的学生的信息
scanf("%s",MGroup[cnt].Name);
printf("请输入此同学的学号:\n");
scanf("%lf",&MGroup[cnt].ID);
printf("请输入此同学的年龄:\n");
scanf("%d",&MGroup[cnt].Age);
printf("请输入此同学的性别:\n");
scanf("%s",&MGroup[cnt].Sex);
printf("请输入此同学的出生日期:\n");
scanf("%d %d %d",&MGroup[cnt].Birthday.y,&MGroup[cnt].Birthday.m,&MGroup[cnt].Birthday.d);
printf("请输入此同学的地址:\n");
scanf("%s",&MGroup[cnt].Address);
printf("请输入此同学的电话:\n");
scanf("%lf",&MGroup[cnt].Phone);
printf("请输入此同学的QQ号码:\n");
scanf("%lf",&MGroup[cnt].QQ);
printf("请输入此同学的邮箱:\n");
scanf("%s",&MGroup[cnt].Email);
fprintf(fpFile,"%s ",MGroup[cnt].Name);//写入信息
fprintf(fpFile,"%.0lf ",MGroup[cnt].ID);
fprintf(fpFile,"%d ",MGroup[cnt].Age);
fprintf(fpFile,"%s ",MGroup[cnt].Sex);
fprintf(fpFile,"%d %d %d ",MGroup[cnt].Birthday.y,MGroup[cnt].Birthday.m,MGroup[cnt].Birthday.d);
fprintf(fpFile,"%s ",MGroup[cnt].Address);
fprintf(fpFile,"%.0lf ",MGroup[cnt].Phone);
fprintf(fpFile,"%.0lf ",MGroup[cnt].QQ);
fprintf(fpFile,"%s\n",MGroup[cnt].Email);
fclose(fpFile);
printf("添加成功!\n");
system("pause");
}
if(flag_add==2)//如果用户输入2,添加信息到指定学生后方
{
printf("要添加信息到哪位同学的后面?\n");
printf("1.输入该同学姓名\n");
printf("2.输入该同学学号\n");
int flag_scanf;//存储用户选择
int target=-1;//存储目标学生的下标
scanf("%d",&flag_scanf);
system("cls");
if(flag_scanf==1)//如果用户输入1,查询目标学生的姓名
{
while(target==-1){
system("cls");
printf("请输入该同学姓名\n");
char name[20];
scanf("%s",name);
for(int i=0;i<GroupSize;i++){//查询目标学生姓名
if(strcmp(MGroup[i].Name,name)==0)
{
target=i;
break;
}
}
}
target++;//添加到目标学生后方,所以下标还要再加一
Stu temp;//临时结构体变量,用来暂时存储要添加的学生的信息
printf("开始添加信息,请输入此同学的姓名:\n");
scanf("%s",temp.Name);
printf("请输入此同学的学号:\n");
scanf("%lf",&temp.ID);
printf("请输入此同学的年龄:\n");
scanf("%d",&temp.Age);
printf("请输入此同学的性别:\n");
scanf("%s",&temp.Sex);
printf("请输入此同学的出生日期:\n");
scanf("%d %d %d",&temp.Birthday.y,&temp.Birthday.m,&temp.Birthday.d);
printf("请输入此同学的地址:\n");
scanf("%s",&temp.Address);
printf("请输入此同学的电话:\n");
scanf("%lf",&temp.Phone);
printf("请输入此同学的QQ号码:\n");
scanf("%lf",&temp.QQ);
printf("请输入此同学的邮箱:\n");
scanf("%s",&temp.Email);
if((fpFile=fopen("info.txt","r+"))==NULL)
{
printf("打开文件失败!\n");
exit(0);
}
int cnt=0;
for(int l=0;feof(fpFile)==0;l++){//读取文件数据并获取文件长度
fscanf(fpFile,"%s %lf %d %s",MGroup[l].Name,&MGroup[l].ID,&MGroup[l].Age,&MGroup[l].Sex);
fscanf(fpFile,"%d %d %d",&MGroup[l].Birthday.y,&MGroup[l].Birthday.m,&MGroup[l].Birthday.d);
fscanf(fpFile,"%s %lf %lf",&MGroup[l].Address,&MGroup[l].Phone,&MGroup[l].QQ);
fscanf(fpFile,"%s",&MGroup[l].Email);
cnt++;
}
fclose(fpFile);
fpFile=fopen("info.txt","w+");//先清空文件内数据
for(int i=cnt;i>target;i--){//将目标学生后方的结构体变量下标往后移1位,腾出一个空位给要添加的学生
MGroup[i]=MGroup[i-1];
}
MGroup[target]=temp;//将要添加的学生的信息赋给目标学生后面一个位置的结构体变量
for(int l=0;l<cnt;l++){//重新写入信息
fprintf(fpFile,"%s ",MGroup[l].Name);
fprintf(fpFile,"%.0lf ",MGroup[l].ID);
fprintf(fpFile,"%d ",MGroup[l].Age);
fprintf(fpFile,"%s ",MGroup[l].Sex);
fprintf(fpFile,"%d %d %d ",MGroup[l].Birthday.y,MGroup[l].Birthday.m,MGroup[l].Birthday.d);
fprintf(fpFile,"%s ",MGroup[l].Address);
fprintf(fpFile,"%.0lf ",MGroup[l].Phone);
fprintf(fpFile,"%.0lf ",MGroup[l].QQ);
fprintf(fpFile,"%s\n",MGroup[l].Email);
}
fclose(fpFile);
printf("添加成功!\n");
system("pause");
}
if(flag_scanf==2)//如果用户输入2,查询目标学生的学号
{
while(target==-1){
system("cls");
printf("请输入该同学学号\n");
double ID;
scanf("%lf",&ID);
for(int i=0;i<GroupSize;i++){//查询目标学生学号
if(MGroup[i].ID==ID)
{
target=i;
break;
}
}
}
target++;//添加到目标学生后方,所以下标还要再加一
Stu temp;//临时结构体变量,用来暂时存储要添加的学生的信息
printf("开始添加信息,请输入此同学的姓名:\n");
scanf("%s",temp.Name);
printf("请输入此同学的学号:\n");
scanf("%lf",&temp.ID);
printf("请输入此同学的年龄:\n");
scanf("%d",&temp.Age);
printf("请输入此同学的性别:\n");
scanf("%s",&temp.Sex);
printf("请输入此同学的出生日期:\n");
scanf("%d %d %d",&temp.Birthday.y,&temp.Birthday.m,&temp.Birthday.d);
printf("请输入此同学的地址:\n");
scanf("%s",&temp.Address);
printf("请输入此同学的电话:\n");
scanf("%lf",&temp.Phone);
printf("请输入此同学的QQ号码:\n");
scanf("%lf",&temp.QQ);
printf("请输入此同学的邮箱:\n");
scanf("%s",&temp.Email);
if((fpFile=fopen("info.txt","r+"))==NULL)
{
printf("打开文件失败!\n");
exit(0);
}
int cnt=0;
for(int l=0;feof(fpFile)==0;l++){//读取文件数据并获取文件长度
fscanf(fpFile,"%s %lf %d %s",MGroup[l].Name,&MGroup[l].ID,&MGroup[l].Age,&MGroup[l].Sex);
fscanf(fpFile,"%d %d %d",&MGroup[l].Birthday.y,&MGroup[l].Birthday.m,&MGroup[l].Birthday.d);
fscanf(fpFile,"%s %lf %lf",&MGroup[l].Address,&MGroup[l].Phone,&MGroup[l].QQ);
fscanf(fpFile,"%s",&MGroup[l].Email);
cnt++;
}
fclose(fpFile);
fpFile=fopen("info.txt","w+");//先清空文件内数据
for(int i=cnt;i>target;i--){//将目标学生后方的结构体变量下标往后移1位,腾出一个空位给要添加的学生
MGroup[i]=MGroup[i-1];
}
MGroup[target]=temp;//将要添加的学生的信息赋给目标学生后面一个位置的结构体变量
for(int l=0;l<cnt;l++){//重新写入数据
fprintf(fpFile,"%s ",MGroup[l].Name);
fprintf(fpFile,"%.0lf ",MGroup[l].ID);
fprintf(fpFile,"%d ",MGroup[l].Age);
fprintf(fpFile,"%s ",MGroup[l].Sex);
fprintf(fpFile,"%d %d %d ",MGroup[l].Birthday.y,MGroup[l].Birthday.m,MGroup[l].Birthday.d);
fprintf(fpFile,"%s ",MGroup[l].Address);
fprintf(fpFile,"%.0lf ",MGroup[l].Phone);
fprintf(fpFile,"%.0lf ",MGroup[l].QQ);
fprintf(fpFile,"%s\n",MGroup[l].Email);
}
fclose(fpFile);
printf("添加成功!\n");
system("pause");
}
}
}
void delinfo()//删除学生信息函数
{
int target=-1;//存储要删除的学生信息结构体变量对应的下标
while(target==-1){//如果找不到对应学生,重复输入过程
system("cls");
printf("请输入要删除的同学的姓名\n");
char name[20];
scanf("%s",name);
for(int i=0;i<GroupSize;i++){//在结构体数组中查找是否有对应的学生
if(strcmp(MGroup[i].Name,name)==0)
{
target=i;
break;
}
}
}
if((fpFile=fopen("info.txt","r+"))==NULL)
{
printf("打开文件失败!\n");
exit(0);
}
int cnt=-1;
for(int l=0;feof(fpFile)==0;l++){//读取文件数据到结构体数组中并获取文件长度
fscanf(fpFile,"%s %lf %d %s",MGroup[l].Name,&MGroup[l].ID,&MGroup[l].Age,&MGroup[l].Sex);
fscanf(fpFile,"%d %d %d",&MGroup[l].Birthday.y,&MGroup[l].Birthday.m,&MGroup[l].Birthday.d);
fscanf(fpFile,"%s %lf %lf",&MGroup[l].Address,&MGroup[l].Phone,&MGroup[l].QQ);
fscanf(fpFile,"%s",&MGroup[l].Email);
cnt++;
}
fclose(fpFile);
fpFile=fopen("info.txt","w+");//清空数据
for(int i=target;i<cnt;i++){//让后面的数据覆盖掉已经删除的数据
MGroup[i]=MGroup[i+1];
}
for(int l=0;l<cnt-1;l++){//重新写入数据
fprintf(fpFile,"%s ",MGroup[l].Name);
fprintf(fpFile,"%.0lf ",MGroup[l].ID);
fprintf(fpFile,"%d ",MGroup[l].Age);
fprintf(fpFile,"%s ",MGroup[l].Sex);
fprintf(fpFile,"%d %d %d ",MGroup[l].Birthday.y,MGroup[l].Birthday.m,MGroup[l].Birthday.d);
fprintf(fpFile,"%s ",MGroup[l].Address);
fprintf(fpFile,"%.0lf ",MGroup[l].Phone);
fprintf(fpFile,"%.0lf ",MGroup[l].QQ);
fprintf(fpFile,"%s\n",MGroup[l].Email);
}
fclose(fpFile);
printf("删除成功!\n");
system("pause");
}
void changeinfo()//修改指定学生电话号码函数
{
int target=-1;//存储要修改的学生的结构体变量对应的下标
while(target==-1){//如果找不到对应学生,重复输入过程
system("cls");
printf("请输入要修改的同学的姓名\n");
char name[20];
scanf("%s",name);
for(int i=0;i<GroupSize;i++){//在结构体数组中查找是否有对应的学生
if(strcmp(MGroup[i].Name,name)==0)
{
target=i;
break;
}
}
}
printf("请输入修改后的电话号码:\n");
double changephone;
scanf("%lf",&changephone);
if((fpFile=fopen("info.txt","r+"))==NULL)
{
printf("打开文件失败!\n");
exit(0);
}
int cnt=-1;
for(int l=0;feof(fpFile)==0;l++){//读取文件数据并获取文件长度
fscanf(fpFile,"%s %lf %d %s",MGroup[l].Name,&MGroup[l].ID,&MGroup[l].Age,&MGroup[l].Sex);
fscanf(fpFile,"%d %d %d",&MGroup[l].Birthday.y,&MGroup[l].Birthday.m,&MGroup[l].Birthday.d);
fscanf(fpFile,"%s %lf %lf",&MGroup[l].Address,&MGroup[l].Phone,&MGroup[l].QQ);
fscanf(fpFile,"%s",&MGroup[l].Email);
cnt++;
}
fclose(fpFile);
fpFile=fopen("info.txt","w+");//先清空数据
MGroup[target].Phone=changephone;
for(int l=0;l<cnt;l++){//重新写入修改后的数据
fprintf(fpFile,"%s ",MGroup[l].Name);
fprintf(fpFile,"%.0lf ",MGroup[l].ID);
fprintf(fpFile,"%d ",MGroup[l].Age);
fprintf(fpFile,"%s ",MGroup[l].Sex);
fprintf(fpFile,"%d %d %d ",MGroup[l].Birthday.y,MGroup[l].Birthday.m,MGroup[l].Birthday.d);
fprintf(fpFile,"%s ",MGroup[l].Address);
fprintf(fpFile,"%.0lf ",MGroup[l].Phone);
fprintf(fpFile,"%.0lf ",MGroup[l].QQ);
fprintf(fpFile,"%s\n",MGroup[l].Email);
}
fclose(fpFile);
printf("修改成功!\n");
system("pause");
}
void deleteall()//清空函数
{
system("cls");
printf("确定清空所有数据?\n");//让用户再次确认是否清空所有信息
system("pause");//暂停程序留给用户反应时间,如用户反悔可关闭程序来取消清空
system("cls");
FILE* del;
del=fopen("info.txt","w+");
fclose(del);
printf("清空成功!\n");
system("pause");
}
void help()//使用说明函数
{
system("cls");
color(6);
printf("\t\t 学生信息管理系统 \n");
printf("\t\t----------------------------------------------------------\n");
color(2);
printf("\t\t 欢迎使用本系统,本系统具有学生信息管理功能,在主 \n");
printf("\t\t 菜单界面的“请输入”后方输入对应数字即可进入相应功 \n");
printf("\t\t 能,例如对学生的信息进行录入,删除,查找,修改, \n");
printf("\t\t 如有需要,还能一键清空所有学生信息。 \n");
printf("\t\t \n");
printf("\t\t \n");
printf("\t\t \n");
printf("\t\t \n");
color(6);
printf("\t\t----------------------------------------------------------\n");
gotoxy(49, 8);
system("pause");//暂停程序让用户观看输出的使用说明
}
void exitsystem()//退出函数
{
gotoxy(20, 12);//跳转光标到一个合适的位置方便接下来的输出
printf("再见,欢迎下次使用\n");
system("pause");
exit(0);
}
共658行,文件输入和输出的部分以及获取文件长度的部分可以进一步抽象成函数以减少代码长度,注释已加在源码中。