Student.h
#pragma once
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#define DEFAULT_SIZE 3
#define INCREASE_SIZE 2
typedef struct Student{
char student_id[20];
char name[20];
int grade;
int class_num;
float score;
}Student;
typedef struct Stulist
{
Student* data;
int count;
int capacity;
}Stulist;
Stulist list;
int InitStulist(Stulist* p);
void DestroyStulist(Stulist* p);
void Add_students(Stulist* p);
void Display_student(Stulist* p);
void Modify_score(Stulist* p);
void Class_statistics(Stulist* p);
void Grade_statistics(Stulist* p);
void ScoreSort(Stulist* p);
void Display_students(Stulist* p);
void Save_data(const Stulist* p);
void Load_data(Stulist* p);
Student.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "Student.h"
void UpCapacity(Stulist* p)
{
if (p->count == p->capacity)
{
Student* ptr = (Student*)realloc(p->data, (p->capacity + INCREASE_SIZE) * sizeof(Student));
if (ptr == NULL)
{
printf("UpCapacity:%s\n", strerror(errno));
return;
}
else
{
p->data = ptr;
p->capacity += INCREASE_SIZE;
printf("增容成功!!!\n");
}
}
}
void Load_data(Stulist* p)
{
FILE* pfRead = fopen("Studentlist.txt", "rb");
if (pfRead == NULL)
{
perror("Load_data");
return;
}
Student tmp = { 0 };
while (fread(&tmp, sizeof(Student), 1,pfRead) == 1)
{
UpCapacity(p);
p->data[p->count] = tmp;
p->count++;
}
fclose(pfRead);
pfRead = NULL;
}
int InitStulist(Stulist* p)
{
assert(p);
p->data =(Student*) calloc(DEFAULT_SIZE, sizeof(Student));
if (p->data == NULL)
{
printf("InitStulist fail\n");
return -1;
}
p->count = 0;
p->capacity = DEFAULT_SIZE;
Load_data(p);
return 0;
}
void DestroyStulist(Stulist* p)
{
assert(p);
free(p->data);
p->data = NULL;
}
int FindByStudent_id(Stulist* p, char student_id[])
{
assert(p);
for (int i = 0; i < p->count; i++)
{
if (0 == strcmp(p->data[i].student_id, student_id))
{
return i;
}
}
return -1;
}
void Add_students(Stulist* p)
{
assert(p);
UpCapacity(p);
printf("请输入学号:>");
scanf("%s", p->data[p->count].student_id);
int ret = FindByStudent_id(p, p->data[p->count].student_id);
if (ret!=-1)
{
printf("该学生已存在,请重新操作\n");
return;
}
printf("请输入姓名:>");
scanf("%s", p->data[p->count].name);
printf("请输入年级:>");
scanf("%d", &p->data[p->count].grade);
printf("请输入班级:>");
scanf("%d", &p->data[p->count].class_num);
printf("请输入成绩:>");
scanf("%f", &p->data[p->count].score);
p->count++;
printf("添加成功\n");
}
void Display_student(Stulist* p)
{
assert(p);
char student_id[20] = { 0 };
printf("请输入学号:>");
scanf("%s", student_id);
int ret = FindByStudent_id(p, student_id);
if (ret == -1)
{
printf("要查找的学生不存在\n");
return;
}
printf("%-20s\t%-20s\t%-5s\t%-5s\t%6s\n",
"学号", "姓名", "年级", "班级", "成绩");
printf("%-20s\t%-20s\t%-5d\t%-5d\t%-6.2f\n",
p->data[ret].student_id,
p->data[ret].name,
p->data[ret].grade,
p->data[ret].class_num,
p->data[ret].score);
}
void Modify_score(Stulist* p)
{
assert(p);
char student_id[20] = { 0 };
printf("请输入学号:>");
scanf("%s", student_id);
int ret = FindByStudent_id(p, student_id);
if (ret == -1)
{
printf("要修改的学生不存在\n");
return;
}
printf("该学生当前成绩为:>%.2f\n", p->data[ret].score);
printf("请输入要修改的目标成绩:>");
scanf("%f", &p->data[ret].score);
}
void Class_statistics(Stulist* p)
{
assert(p);
int class_num;
float total_score = 0, max_score = 0, min_score = 200;
int pass_cnt = 0;
printf("请输入班级:>");
scanf("%d", &class_num);
for (int i = 0; i < p->count; i++)
{
if (p->data[i].class_num == class_num)
{
total_score += p->data[i].score;
if (p->data[i].score > max_score)
{
max_score = p->data[i].score;
}
if (p->data[i].score < min_score)
{
min_score = p->data[i].score;
}
if (p->data[i].score >= 90)
{
pass_cnt++;
}
}
}
float average_score = total_score / p->count;
float pass_rate = (float)pass_cnt / p->count;
printf("%-5s\t%-9s\t%-7s\t%-7s\t%-7s\n",
"班级", "平均成绩", "最高分", "最低分", "及格率");
printf("%-2d\t%-6.2f\t%-6.2f\t%-6.2f\t%-5.2f%%\n",
class_num, average_score, max_score, min_score, pass_rate);
}
void Grade_statistics(Stulist* p)
{
assert(p);
int grade;
float total_score = 0, max_score = 0, min_score = 200;
int pass_cnt = 0;
printf("请输入年级:>");
scanf("%d", &grade);
for (int i = 0; i < p->count; i++)
{
if (p->data[i].grade == grade)
{
total_score += p->data[i].score;
if (p->data[i].score > max_score)
{
max_score = p->data[i].score;
}
if (p->data[i].score < min_score)
{
min_score = p->data[i].score;
}
if (p->data[i].score >= 90)
{
pass_cnt++;
}
}
}
float average_score = total_score / p->count;
float pass_rate = (float)pass_cnt / p->count;
printf("%-5s\t%-9s\t%-7s\t%-7s\t%-7s\n",
"年级", "平均成绩", "最高分", "最低分", "及格率");
printf("%-2d\t%-6.2f\t%-6.2f\t%-6.2f\t%-5.2f%%\n",
grade, average_score, max_score, min_score, pass_rate);
}
int cmp_score(const void* e1, const void* e2)
{
return ((*(Student*)e2).score - (*(Student*)e1).score);
}
void ScoreSort(Stulist* p)
{
assert(p);
qsort(p->data, p->count, sizeof(Student), cmp_score);
printf("排序成功\n");
}
void Display_students(Stulist* p)
{
assert(p);
ScoreSort(p);
printf("%-20s\t%-20s\t%-5s\t%-5s\t%6s\n",
"学号", "姓名", "年级", "班级", "成绩");
for (int i = 0; i < p->count; i++)
{
printf("%-20s\t%-20s\t%-5d\t%-5d\t%-6.2f\n",
p->data[i].student_id,
p->data[i].name,
p->data[i].grade,
p->data[i].class_num,
p->data[i].score);
}
}
void Save_data(const Stulist* p)
{
assert(p);
FILE* pfWrite = fopen("Studentlist.txt", "wb");
if (pfWrite == NULL)
{
perror("Load_data");
return;
}
for (int i = 0; i < p->count; i++)
{
fwrite(p->data + i, sizeof(Student), 1, pfWrite);
}
fclose(pfWrite);
pfWrite = NULL;
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "Student.h"
enum option
{
Exit,
Display,
Add,
Modify,
Sort,
Class_statistic,
Grade_statistic
};
void menu()
{
printf("************************* MENU ************************\n");
printf("********** 1.成绩查看 2.成绩录入 **********\n");
printf("********** 3.成绩修改 4.成绩排序 **********\n");
printf("********** 5.班级成绩统计 6.年级成绩统计 **********\n");
printf("********** 0.退出 **********\n");
printf("************************************************************\n");
}
void switch_case1(int input)
{
switch (input)
{
case Display:
case Add:
case Modify:
printf("无权限使用此功能,请重新选择\n");
break;
case Sort:
Display_students(&list);
break;
case Class_statistic:
Class_statistics(&list);
break;
case Grade_statistic:
Grade_statistics(&list);
break;
case Exit:
printf("已退出学生成绩管理系统\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
}
void switch_case2(int input)
{
switch (input)
{
case Display:
Display_student(&list);
break;
case Add:
Add_students(&list);
break;
case Modify:
Modify_score(&list);
printf("修改成功\n");
break;
case Sort:
case Class_statistic:
case Grade_statistic:
printf("无权限使用此功能,请重新选择\n");
break;
case Exit:
Save_data(&list);
DestroyStulist(&list);
printf("已退出学生成绩管理系统\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
}
int login()
{
int flag = 0;
int N = 3,cnt=0;
char username[20];
char password[20];
printf("******************** 学生信息管理系统 *******************\n");
printf("请输入用户名和密码:>\n");
while (N--)
{
printf("username:>");
scanf("%s", username);
printf("password:>");
scanf("%s", password);
if (strcmp(username, "admin") == 0 && strcmp(password,"12345")==0)
{
printf("登录成功(管理员)\n");
flag = 1;
cnt++;
break;
}
else if(strcmp(password, "12345")==0)
{
printf("登录成功(普通用户)\n");
flag = 0;
cnt++;
break;
}
if (N >= 1)
{
printf("用户名和密码错误,请重新输入\n");
}
else
printf("用户名和密码错误\n");
}
if (cnt == 0)
flag = -1;
return flag;
}
int main()
{
int input;
InitStulist(&list);
int ret = login();
if (ret == 1)
{
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch_case1(input);
} while (input);
}
else if(ret == 0)
{
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch_case2(input);
} while (input);
}
else
{
printf("登录失败,请稍后重试\n");
}
return 0;
}