目录
一、目标
二、实现(学习请看这)
1.设计结构体存储学生信息
2.申明全局变量
3.申明操作函数
4.函数具体实现
4.1 录入学生信息
4.2 读取文件函数
4.3 保存文件函数
4.4成绩排序函数
4.5 修改学生信息
4.6 删除学生信息
4.7 显示学生信息
4.8 查找学生信息
4.9 菜单函数
5 主函数
三、代码(搬运请看这)
四、界面展示和代码分享
1.主界面
2.先从文件中读取学生信息,再显示所有信息
3.录入学生信息
4.删除学生信息
5.成绩排序
6.下载链接
五、代码交流分享
对学生信息(学号、姓名、性别、寝室号、手机号码、成绩)进行统一管理。且实现如下功能
1.手动录入学生信息;
2.从文本(student.txt)中读取学生信息;
3.保存学生信息到文本(student.txt)中;
4.对学生成绩进行升序或降序排列(提供排序方式供操作者选择);
5.修改学生各项信息;
6.删除某个学生的信息;
7.显示所有学生的信息;
8.查找某个学生的信息。
struct student
{
char no[10];//学号
char name[15];//姓名
char sex[7];//性别
char dor[10];//宿舍号码
char tel[16];//电话号码
int score;//成绩
};
struct student stu[20];//结构体数组
int len=0;//结构体数组中元素的数量
通过结构体数组实现学生信息的存储及相关操作,定义len来实时更新结构体数组中实际的学生个数
从数据结构的角度看,一般C语言的管理系统可以用两种结构实现,一种是顺序表即本文采用的结构体数组,另一种是链表,两者都从属于线性表。
void AddStudent(); //从键盘录入学生信息
void ReadStudent(); //从文本中读取学生信息
void SaveStudent(); //将学生信息保存至文本
void SortStudent(); //对学生成绩进行排序
void ModifyStudent(); //修改学生信息
void DeleteStudent(); //删除学生信息
void ShowStudent(); //显示学生信息
void FindStudent(); //查询学生信息
这里的7个函数分别对应于上述的7个功能点,通过具体的某一个函数来实现具体的某一个功能。
void AddStudent()
{
printf("请输入学号:");
scanf("%s",stu[len].no);
printf("请输入姓名:");
scanf("%s",stu[len].name);
printf("请输入性别:");
scanf("%s",stu[len].sex);
printf("请输入宿舍号码:");
scanf("%s",stu[len].dor);
printf("请输入电话号码:");
scanf("%s",stu[len].tel);
while(1){
printf("请输入成绩:");
scanf("%d",&stu[len].score);
if(stu[len].score<0||stu[len].score>100)
printf("输入成绩有误!\n");
else
break;
}
len++;
system("pause");
}
这里单独对学生的成绩进行了判断,避免了非法输入的问题。当然,对学号、姓名、性别、宿舍号码、电话号码也可以进行类似的判断。如学号必须为7位、姓名不得包含数字、性别只能为男或者女、宿舍号码必须为5位、电话号码必须为8位。
有人可能会对scanf中的stu[len]有疑问。下面举例说明:
当数组中有两个学生信息的时候,len = 2。此时数组中stu[0]和stu[1]存放着这两个学生的信息,调用AddStudent函数,新的学生的信息自然写入到stu[2]这个元素中,而len正好等于2。写入完毕,此时数组中的元素个数变为3,于是通过len++这个语句将len增加为3。此时数组中stu[0]、stu[1]、stu[2]储存着3个学生的信息,len = 3, 下次会将学生信息写入stu[3]中。
void ReadStudent()
{
FILE *fp;
fp=fopen("student.txt","r");
if(fp==NULL)
{
printf("文件不存在!");
exit(1);
}
while(fscanf(fp,"%s\t%s\t%s\t%s\t%s\t%d",stu[len].no,stu[len].name,stu[len].sex,stu[len].dor,\
stu[len].tel,&stu[len].score)!=EOF)
{
len++;
}
fclose(fp);
printf("读取完毕!");
system("pause");
}
首先申明文件指针变量fp,再通过调用fopen函数打开student.txt文件,"r"的意思是用read的方式打开,即只读取文件,不修改文件的内容。
若文件指针为空,说明打开文件失败,一般是student.txt文件和你的.c或.cpp文件不在同一个目录下.当你编译运行.c或.cpp文件时,计算机只会在当前文件夹内搜索student.txt。这是因为我写的是相对路径,如果你的student.txt放在D盘的某个文件夹下,你可以在fopen中写入绝对路径如:
fp=fopen("D:\\123\\student.txt","r");
fscanf是文件读取函数,和普通的scanf函数类似,只不过比他多了一个文件指针的参数,在本文就是fp。
fscanf这个函数和scanf函数一样,都会有返回值(平常大家用scanf函数的时候一般都忽略了它的返回值)。事实上,大部分系统函数都具有返回值,用以判断函数执行是否成功。
fscanf也一样,当fscanf函数读取到了文件的尾部,他的返回值就会变成EOF。所以我们可以使用EOF来进行辅助判断,判断文件是否读取完毕。
第一次循环,len = 0,文件中读取的第一个学生的信息会存入到stu[0]中;
第二次循环,len = 1,文件中读取的第二个学生的信息会存入到stu[1]中;
第二次循环,len = 2,文件中读取的第三个学生的信息会存入到stu[2]中......
读取完毕后,记得调用fclose函数关闭文件。有开有关,再开不难。
ps: fscanf里面的\t是制表符的意思,就是键盘上的Tab键,为什么读取的时候要读取Tab键?因为我在写入的时候用Tab来分隔数据,所以读取的时候也需要读取Tab,防止Tab被读入到其他变量中。
void SaveStudent()
{
FILE *fp;
int i;
fp=fopen("student.txt","w");
if(fp==NULL)
{
printf("文件不存在!");
exit(1);
}
for(i=0;i
参考4.2,这里的fopen的第二个参数变成了"w",即write,意思是用写入的方式打开student.txt。
参照fscanf,自然就想到了fprintf,这里fprintf的第二个参数和4.2中的fscanf的第二个参数基本一致,只不过最后多了一个\n,意思是每行仅写入一个学生的各项信息,用行来分隔各个学生的信息。
void SortStudent()
{
int type;
struct student s;
int i,j;
printf("0.按分数降序排序;1.按分数升序排序\n请输入排序方式:\n");
scanf("%d",&type);
if (type==0)//降序排列
{
for(i=0;istu[j+1].score)
{
s=stu[j];
stu[j]=stu[j+1];
stu[j+1]=s;
}
}
}
}
ShowStudent();
}
这里的排序用到了基础的排序方法——冒泡排序。升序和降序的区别是 stu[j].score>stu[j+1].score 中的大于号和小于号
void ModifyStudent()
{
char s[10];
int k;
printf("请输入要修改的学生的学号:");
scanf("%s",s);
for(k=0;k
获取要修改的学生的学号s,对数组stu进行遍历,将每个学生的学号与s进行匹配,strcmp函数可以比较两个字符串,当两个字符串完全一致,该函数返回0
查找到该学生后,重新录入新的学生信息(覆盖掉原先的数据)实现学生信息的修改,并通过return 结束函数
如果没有查询到该学生,通过printf输出提示。
void DeleteStudent()
{
char s[10];
int k,p;
printf("请输入要删除的学生的学号:");
scanf("%s",s);
for(k=0;k
删除函数同修改函数类似,通过学号查询到该学生。不同的是,不断循环将下一个元素写入当前元素,实现学生信息的删除。
如现在stu数组中有6个学生的信息,欲删除第4个学生的信息,即stu[3]。首先通过学号查找到该学生,此时k = 3, 令p = 3; p < 5 ; p++
stu[3] = stu[4] 将第五个学生信息stu[4]写入之前的第四个学生信息stu[3];
stu[4] = stu[5] 将第六个学生信息stu[5]写入之前的第五个学生信息stu[4];
len -- 将 len 变为 5, 此时stu数组中存放了 stu[0]、stu[1]、stu[2]、stu[3]、stu[4]。
void ShowStudent()
{
int k;
printf("学号\t 姓名\t性别 宿舍号码 电话号码\t成绩 \n");
for(k=0;k
遍历stu数组,依次输出数组中的学生信息。为什么有"%3s"、"\t"、" %8s"呢?当然是为了输出的时候能对齐了。
void FindStudent()
{
char s[10];
int k;
int type;
printf("1.按姓名查找;2.按学号查找\n请输入查询方式:\n");
scanf("%d",&type);
if(type==1){
printf("请输入要查询的姓名:");
scanf("%s",s);
for(k=0;k
查找和修改、删除类似,只不过把查找到的信息输出了而已。可以在查找要删除和修改学生信息之前,效仿4.8将学生信息预先输出,以确保删除的是指定的学生。
void Menu()
{
system("cls");
printf("\t\t=======学生信息管理系统=======\n\n");
printf("\t\t=====作者微信: qczsbwjzjn=====\n\n");
printf("\t0.从文件中读取学生信息 ");
printf("1.从键盘中录入学生信息\n\n");
printf("\t2.修改学生信息\t");
printf("\t3.删除学生信息\n\n");
printf("\t4.查询学生信息\t");
printf("\t5.显示所有信息\n\n");
printf("\t6.学生成绩排序\t");
printf("\t7.保存并退出系统\n\n");
printf("\t\t请输入选择:");
}
int main() //主函数
{//正常退出系统才会保存数据,直接关闭无法将数据保存至文件
int s=1;
while(1){
Menu();
scanf("%d",&s);
switch(s){
case 0:ReadStudent();break;
case 1:AddStudent();break;
case 2:ModifyStudent();break;
case 3:DeleteStudent();break;
case 4:FindStudent();break;
case 5:ShowStudent();break;
case 6:SortStudent();break;
case 7:SaveStudent();return 0;
}
}
}
#include
#include
#include
//Author Wechat:qczsbwjzjn
//-----定义结构体存储学生信息-------
struct student
{
char no[10];//学号
char name[15];//姓名
char sex[7];//性别
char dor[10];//宿舍号码
char tel[16];//电话号码
int score;//成绩
};
//-------申明全局变量------
struct student stu[20];//结构体数组
int len=0;//结构体数组中元素的数量
//------申明函数----------
void AddStudent(); //从键盘录入学生信息
void ReadStudent(); //从文本中读取学生信息
void SaveStudent(); //将学生信息保存至文本
void SortStudent(); //对学生成绩进行排序
void ModifyStudent(); //修改学生信息
void DeleteStudent(); //删除学生信息
void ShowStudent(); //显示学生信息
void FindStudent(); //查询学生信息
//------函数实现---------
void AddStudent()
{
printf("请输入学号:");
scanf("%s",stu[len].no);
printf("请输入姓名:");
scanf("%s",stu[len].name);
printf("请输入性别:");
scanf("%s",stu[len].sex);
printf("请输入宿舍号码:");
scanf("%s",stu[len].dor);
printf("请输入电话号码:");
scanf("%s",stu[len].tel);
while(1){
printf("请输入成绩:");
scanf("%d",&stu[len].score);
if(stu[len].score<0||stu[len].score>100)
printf("输入成绩有误!\n");
else
break;
}
len++;
system("pause");
}
void ReadStudent()
{
FILE *fp;
fp=fopen("student.txt","r");
if(fp==NULL)
{
printf("文件不存在!");
exit(1);
}
while(fscanf(fp,"%s\t%s\t%s\t%s\t%s\t%d",stu[len].no,stu[len].name,stu[len].sex,stu[len].dor,\
stu[len].tel,&stu[len].score)!=EOF)
{
len++;
}
fclose(fp);
printf("读取完毕!");
system("pause");
}
void SaveStudent()
{
FILE *fp;
int i;
fp=fopen("student.txt","w");
if(fp==NULL)
{
printf("文件不存在!");
exit(1);
}
for(i=0;istu[j+1].score)
{
s=stu[j];
stu[j]=stu[j+1];
stu[j+1]=s;
}
}
}
}
ShowStudent();
}
void ModifyStudent()
{
char s[10];
int k;
printf("请输入要修改的学生的学号:");
scanf("%s",s);
for(k=0;k
其他功能就不展示了,自己运行代码吧
代码下载链接,内含student.txt文件和少量数据
学生信息管理系统.rar-C文档类资源-CSDN下载
代码交流分享群:877518298
加群需要审核,如果不想进去可以直接关注微信公众号,回复“管理系统”即可获得代码资源