img
img
img
/*
学生成绩管理系统
2020年12月27日17点09分
*/
#define _CRT_SECURE_NO_WARNINGS //在visual studio中关闭安全检查
#include<stdio.h>
#include<stdlib.h>
struct student//结构体student定义
{
int number;//学号
char name[20];//姓名
int account_chinese;//语文成绩
int account_math;//数学成绩
int account_english;//英语成绩
};
//ASCI函数原型
void sutdents_information_input(void);//学生信息输入
void students_information_output(struct student* p, int i);//学生信息输出
void students_information_search(struct student* p, int i);//学生信息查找
void students_information_modify(struct student* p, int i);//学生信息修改并输出
void account_average(struct student* p, int i);//计算学生的综合成绩
void delete(struct student* p, int i);//删除学生的信息
void add(struct student* p, int i);//增加学生的信息
void account_select(struct student* p, int i);//查找平均分大于80分的学生的信息
void bank(struct student* p, int i);//排名
int main(void)
{
//变量声明
FILE* pfile;
char ch;
int i, n;
struct student* pdata;
//开始文件读取,通过文件的数据的行数,计算结构体student素组的元素个数
flag1:
pfile = NULL, i = 0, n = 0, pdata = NULL, ch = 0;
pfile = fopen("1.txt", "r+");
printf("文件正在读取中...\n");
while ((ch = fgetc(pfile)) != EOF)
{
if (ch == '\n')
i++;
}
n = i;
pdata = (struct student*)malloc(i * sizeof(struct student));//申请分配动态内存
i = 0;
rewind(pfile);
while (i < n)
{
fscanf(pfile, "%d %s %d %d %d", &pdata[i].number, pdata[i].name, &pdata[i].account_chinese, &pdata[i].account_math, &pdata[i].account_english);
i++;
//利用fscanf()从文件内读取数据
}
rewind(pfile);
fclose(pfile);
system("cls");
printf("读取完毕\n");
puts("***************MENU***************");
printf("1:学生信息录入\n2:学生基本信息输出\n3:按学号查询学生信息\n4:按学号修改某学生的信息并输出\n5:求每个人的平均成绩\n6:删除某学生的信息\n7:添加某学生信息\n8:输出平均分大于80分学生的同学信息\n9:根据总成绩或平均成绩综合排名\nq:退出\n");
while ((ch = getchar()) != 'q')//switch与while实现菜单的交互功能
{
//在对源文件进行了覆盖操作后,关闭文件指针,重新打开新文件,这里利用了goto实现
switch (ch)
{
case'1':
sutdents_information_input();
free(pdata);
getchar();
goto flag1;
break;
case'2':
students_information_output(pdata, n);
free(pdata);
getchar();
goto flag1;
break;
case'3':
students_information_search(pdata, n);
free(pdata);
getchar();
goto flag1;
break;
case'4':
students_information_modify(pdata, n);
free(pdata);
getchar();
goto flag1;
break;
case'5':
account_average(pdata, n);
free(pdata);
getchar();
goto flag1;
break;
case'6':
delete(pdata, n);
free(pdata);
getchar();
goto flag1;
break;
case'7':
add(pdata, n);
free(pdata);
getchar();
goto flag1;
break;
case'8':
account_select(pdata, n);
free(pdata);
getchar();
goto flag1;
break;
case'9':
bank(pdata, n);
free(pdata);
getchar();
goto flag1;
break;
default:
printf("输入错误请重试\n");
}
}
fclose(pfile);
free(pdata);
return 0;
}
void sutdents_information_input(void)
{
printf("请于记事本中进行信息录入\n");
system("1.txt");//利用命令行打开文件1.txt进行编辑
}
void students_information_output(struct student* p, int i)
{
int n = 0;
printf("学号 姓名 语文 数学 英语 \n");
while (n < i)
{
printf("%7d %-15s %5d %5d %5d\n", p[n].number, p[n].name, p[n].account_chinese, p[n].account_math, p[n].account_english);
n++;//利用printf()实现格式化输出
}
printf("任意按键请继续...");
getchar();
}
void students_information_search(struct student* p, int i)
{
int search = 0, n = 0;
_Bool flag = 1;
//设立search存储查找目标,flag用于标记是否查找成功,n为循环自变量
printf("请输入您要查找的学生学号:");
scanf("%d", &search);
getchar();
while (n < i)//在这里使用了顺序查找
{
if (p[n].number == search)
{
flag = 0;
printf("学号 姓名 语文 数学 英语 \n");
printf("%7d %-15s %5d %5d %5d\n", p[n].number, p[n].name, p[n].account_chinese, p[n].account_math, p[n].account_english);
break;//找到则退出循环
}
n++;
}
if (flag)
printf("没有找到此学生信息\n");
printf("任意按键请继续...");
}
void students_information_modify(struct student* p, int i)
{
FILE* pfile = fopen("1.txt", "w");
int search = 0, n = 0;
int inside = 0;
char ch;
_Bool flag = 1;
//设立search存储查找并修改的目标,flag标记是否修改成功
printf("请输入您要修改的学生的学号:");
scanf("%d", &search);
getchar();
while (n < i)
{
if (p[n].number == search)
{
flag = 0;//找到目标,flag设为0
printf("请修改:\n");
printf("学号 姓名 语文 数学 英语\n");
scanf("%d %s %d %d %d", &p[n].number, p[n].name, &p[n].account_chinese, &p[n].account_math, &p[n].account_english);
getchar();
break;
}
n++;
}
n = 0;
while (n < i)//对文件进行覆盖写入
{
fprintf(pfile, "%d %s %d %d %d\n", p[n].number, p[n].name, p[n].account_chinese, p[n].account_math, p[n].account_english);
n++;
}
if (flag)
printf("修改失败\n");
else
printf("修改完毕\n");
rewind(pfile);
fclose(pfile);
pfile = fopen("1.txt", "r");
printf("学号 姓名 语文 数学 英语\n");
while ((ch = fgetc(pfile)) != EOF)
{
putchar(ch);
}
fclose(pfile);
printf("任意按键请继续...");
}
void account_average(struct student* p, int i)
{
int n = 0;
printf("学号 姓名 语文 数学 英语 平均分 \n");
while (n < i)
{
float ave = (p[n].account_chinese + p[n].account_math + p[n].account_english) / 3.0;//设立局部变量ave计算每一个学生的平均分并被输出
printf("%7d %-15s %5d %5d %5d %.2f\n", p[n].number, p[n].name, p[n].account_chinese, p[n].account_math, p[n].account_english, ave);
n++;
}
printf("任意按键请继续...");
getchar();
}
void delete(struct student* p, int i)
{
FILE* pfile = fopen("1.txt", "w");
int search, n = 0, inside = 0;
_Bool flag = 1;
printf("请输入您想要删除信息的学生的学号:");
scanf("%d", &search);
getchar();
while (n < i)
{
if (p[n].number == search)//同样利用标记变量search
break;
n++;
}
while (inside < i)
{
if (inside == n)//当遍历到删除目标时,跳过输出此数据,继续输出下面的内容
{
flag = 0;
inside++;
continue;
}
else
fprintf(pfile, "%d %s %d %d %d\n", p[inside].number, p[inside].name, p[inside].account_chinese, p[inside].account_math, p[inside].account_english);//在这里是使用了对原文本删除并重新写入的操作
inside++;
}
if (flag)
printf("删除失败\n");
else
printf("删除成功\n");
fclose(pfile);//关闭文件
printf("任意按键请继续...");
getchar();
}
void add(struct student* p, int i)
{
FILE* pfile = fopen("1.txt", "w");
int n = 0;
struct student dataqe;
printf("请输入您要添加的学生的信息\n");
printf("学号 姓名 语文 数学 英语\n");
scanf("%d %s %d %d %d", &dataqe.number, dataqe.name, &dataqe.account_chinese, &dataqe.account_math, &dataqe.account_english);
getchar();
while (n < i)//同样时利用先删除再写入
{
fprintf(pfile, "%d %s %d %d %d\n", p[n].number, p[n].name, p[n].account_chinese, p[n].account_math, p[n].account_english);
n++;
}
fprintf(pfile, "%d %s %d %d %d\n", dataqe.number, dataqe.name, dataqe.account_chinese, dataqe.account_math, dataqe.account_english);
fclose(pfile);//在原数据最后增加上新数据
//在文件的尾部进行增添处理
printf("任意按键请继续...");
getchar();
}
void account_select(struct student* p, int i)
{
int n = 0;
printf("学号 姓名 语文 数学 英语 平均分 \n");
while (n < i)
{
float ave = 0;//局部变量
ave = (p[n].account_chinese + p[n].account_math + p[n].account_english) / 3.0;
if (ave >= 80.0)
{
printf("%7d %-15s %5d %5d %5d %.2f\n", p[n].number, p[n].name, p[n].account_chinese, p[n].account_math, p[n].account_english, ave);
}
n++;
}
printf("任意按键请继续...");
getchar();
}
void bank(struct student* p, int i)
{
int x, y;
struct grade//新定义结构体,作为标签以便排序
{
int number;
int grade;
};
struct grade* bank = (struct grade*)malloc(i * sizeof(struct grade));//动态内存分配
x = 0;
while (x < i)//遍历对结构体数组赋值以作为标签使用
{
bank[x].number = p[x].number;
bank[x].grade = p[x].account_chinese + p[x].account_math + p[x].account_english;
x++;
}
for (x = 0; x < i - 1; x++)//选择排序
{
for (y = x + 1; y < i; y++)
{
if (bank[x].grade < bank[y].grade)
{
bank[x].grade = bank[x].grade + bank[y].grade;
bank[y].grade = bank[x].grade - bank[y].grade;
bank[x].grade = bank[x].grade - bank[y].grade;
int c = bank[x].number;
bank[x].number = bank[y].number;
bank[y].number = c;
//两种数据交换方式
}
}
}
x = 0;
printf("学号 姓名 语文 数学 英语 平均分 总分 排名\n");
while (x < i)//通过标签一次输出
{
int inside = 0;
while (inside < i)
{
if (bank[x].number == p[inside].number)//查找通标签相等的成员,并输出结构体
{
printf("%7d %-15s %5d %5d %5d %.2f %5d %5d\n", p[inside].number, p[inside].name, p[inside].account_chinese, p[inside].account_math, p[inside].account_english, bank[x].grade / 3.0, bank[x].grade, x + 1);
break;//退出当前查找,继续查找下一个标签指向的内容
}
inside++;
}
x++;
}
printf("任意按键请继续...");
getchar();
}