展示
头文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>//输入输出函数
#include<stdlib.h>//动态分配函数和随机函数
#include<windows.h>//控制台程序,用来实现cmd指令,title指令,cls指令等等
#include<locale.h>//本地化,用于控制从标准库中对于不同地区会产生不一样行为的部分
#include<string.h>//字符串函数
//宏定义,学科排序
#define functioncreate(major) void major##compare(mana mn){\
int i,j,sum=mn->sum;\
for(i=0;i<sum-1;i++)\
for(j=0;j<sum-i-1;j++)\
if(mn->student[j].grade->major<mn->student[j+1].grade->major)\
swap(&mn->student[j],&mn->student[j+1]);\
}
typedef struct a1 { //学生成绩信息
int Chinese;
int Math;
int English;
int Physics;
int Chemistry;
int Organism;
int All;
}*grade;
typedef struct a2 { //学生信息 自定义结构体
char name[10];
char stunum[20];
grade grade;
int Class;
}*student;
typedef struct a3 { //全体学生信息 自定义结构体
int sum;
student student;
int capacity;
}*mana;
typedef struct m {
int kind;
char account[20];
char password[20];
char stunum[20];
}acco;
void setpos(short x, short y); //设置位置
void init(); //初始化
void welcome(); //欢迎界面
void manager(mana mn); //开始
void menu(); //菜单
void addstu(mana mn);//加入
void initmana(mana mn);// 初始化
void exportcapacity(mana mn);//扩容
void modifystu(mana mn);//修改个人
void showsin(student stu, int i);//展示单人
void showall(mana mn);
void clean(mana mn);//清空
void swap(student p1, student p2);
void compare(mana mn);
void initstu(student mn);
void stunumcompare(mana mn);
void enter();
int identify(int a);
void regist();
void read(mana all);
void save(mana all);
void clear(mana all);
void teacher(mana all);
void stu(mana all);
源文件
#include "FileName.h"
// 检查字符串是否全部为字母
bool is_alpha(const char* s) {
for (int i = 0; i < strlen(s); i++) {
if (!isalpha(s[i])) {
return false;
}
}
return true;
}
// 检查字符串是否全部为数字
bool is_number(const char* s) {
for (int i = 0; i < strlen(s); i++) {
if (!isdigit(s[i])) {
return false;
}
}
return true;
}
// 设置控制台光标位置
void setpos(short x, short y) {
HANDLE mn = GetStdHandle(STD_OUTPUT_HANDLE);
//此处运用句柄,句柄可以理解为一个可以操作其他设备的东西//
COORD pos = { x,y };
//COORD是windows APL中定义的一个结构体,表示一个字符在控制台屏幕缓冲区上的坐标
SetConsoleCursorPosition(mn, pos);
}
// 初始化控制台,隐藏光标
void init() {
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//STD_OUTPUT_HANDLE即为输出设备,可理解为窗口
//影藏光标操作
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);
//获取控制台光标信息,检索有关指定控制台屏幕缓冲区的光标大小和可见性的信息
CursorInfo.bVisible = false;//隐藏控制台光标
SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态
}
// 显示欢迎界面
void welcome() {
init();
system("title 学生成绩管理系统");//运用title指令修改窗口指令为“学生成绩管理系统”
system("mode con cols=100 lines=30");//运用cmd指令将黑窗大小设置为30行,100列的大小
setpos(40, 12);//定义上面那行字出现的位置
printf("欢迎来到学生成绩管理系统");
setpos(40, 13);
system("pause");//运用pause指令,用处是按下任意键才能指向下一操作
}
// 显示主菜单
void menu() {//菜单
system("cls");//cls指令:清除1
setpos(30, 5);
printf("请点击相应按键决定您的下一步操作");
setpos(30, 10);
printf("1.添加新学生-------2.清空");
setpos(30, 12);
printf("3.排序---------------4.班级排名");
setpos(30, 14);
printf("5.修改学生信息-----6.查看学生成绩");
setpos(30, 16);
printf("------------0.退出-----------");
setpos(38, 20);
}
// 初始化管理结构
void initmana(mana mn) {
mn->capacity = 0;
mn->student = NULL;
mn->sum = 0;
}
// 扩展学生数组容量
void exportcapacity(mana mn) {
if (mn->capacity > mn->sum)
return;
int capacity = mn->capacity == 0 ? 1 : 2 * mn->capacity;
student temp = (student)realloc(mn->student, sizeof(struct a2) * capacity);
if (temp == NULL) {
printf("Error: could not allocate memory\n");
return;
}
mn->student = temp;
mn->capacity = capacity;
}
// 获取用户输入并验证
void get_input(const char* prompt, char* input, bool(*validate)(const char*)) {
do {
system("cls");
setpos(30, 10);
printf("%s", prompt);
scanf("%s", input);
} while (!validate(input));
}
// 初始化学生信息,包括班级信息
void initstu(student mn) {
student now = mn;
int sum = 0;
char temp[100];
get_input("请输入新学生的姓名(拼音):", temp, is_alpha);
strcpy(now->name, temp);
char stunum[100];
get_input("请输入新学生的学号:", stunum, is_number);
strcpy(now->stunum, stunum);
char classStr[100];
get_input("请输入新学生的班级:", classStr, is_number);
now->Class = atoi(classStr);
int Chinese, Math, English, Physics, Chemistry, Organism;
int* subjects[] = { &Chinese, &Math, &English, &Physics, &Chemistry, &Organism };
const char* subject_names[] = { "语文", "数学", "英语", "物理", "化学", "生物" };
for (int i = 0; i < 6; i++) {
char score[100];
char prompt[50];
sprintf(prompt, "请输入%s成绩:", subject_names[i]);
get_input(prompt, score, is_number);
*subjects[i] = atoi(score);
sum += *subjects[i];
}
now->grade->Chinese = Chinese;
now->grade->Math = Math;
now->grade->English = English;
now->grade->Physics = Physics;
now->grade->Chemistry = Chemistry;
now->grade->Organism = Organism;
now->grade->All = sum;
system("cls");
}
// 学号比较函数,用于排序
void stunumcompare(mana mn) {
int i, j, sum = mn->sum;
for (i = 0; i < sum - 1; i++) {
for (j = 0; j < sum - i - 1; j++) {
if (strcmp(mn->student[j].stunum,mn->student[j+1].stunum))
swap(&mn->student[j], &mn->student[j + 1]);
}
}
}
// 添加新学生
void addstu(mana mn) {
system("cls");
exportcapacity(mn);
mn->student[mn->sum].grade = (grade)malloc(sizeof(struct a1));
initstu(&mn->student[mn->sum]);
mn->sum++;
setpos(40, 10);
printf("加入完成");
setpos(40, 12);
system("pause");
system("cls");
}
// 修改学生信息
void modifystu(mana mn) {
system("cls");
setpos(30, 10);
int sum = 0;
printf("请输入你要修改的学生名字(拼音):");
char s[10];
scanf("%s", s);
int i;
for (i = 0; i < mn->sum; i++) {
if (strcmp(s, mn->student[i].name) == 0)
break;
}
system("cls");
if (i == mn->sum) {
setpos(30, 10);
printf("查无此人,");
system("pause");
return;
}
student now = &(mn->student[i]);
initstu(now);
}
// 显示单个学生信息,包括班级
void showsin(student stu, int i) {
setpos(20, 5 + 2 * i);
printf("%d", stu->Class); // 显示班级信息
setpos(25, 5 + 2 * i);
printf("%s", stu->name); // 显示学生姓名
setpos(30, 5 + 2 * i);
printf("%s", stu->stunum); // 显示学号
setpos(35, 5 + 2 * i);
printf("%d", stu->grade->Chinese); // 显示语文成绩
setpos(40, 5 + 2 * i);
printf("%d", stu->grade->Math); // 显示数学成绩
setpos(45, 5 + 2 * i);
printf("%d", stu->grade->English); // 显示英语成绩
setpos(50, 5 + 2 * i);
printf("%d", stu->grade->Physics); // 显示物理成绩
setpos(55, 5 + 2 * i);
printf("%d", stu->grade->Chemistry); // 显示化学成绩
setpos(60, 5 + 2 * i);
printf("%d", stu->grade->Organism); // 显示生物成绩
setpos(65, 5 + 2 * i);
printf("%d", stu->grade->All); // 显示总分
}
// 显示所有学生信息,包括表头
void showall(mana mn) {
int i = 0, sum = mn->sum;
if (sum == 0) {
setpos(45, 13);
printf("暂空"); // 若无学生信息,显示暂空
}
system("cls");
// 显示表头
setpos(20, 3);
printf("班级");
setpos(25, 3);
printf("姓名");
setpos(30, 3);
printf("学号");
setpos(35, 3);
printf("语文");
setpos(40, 3);
printf("数学");
setpos(45, 3);
printf("英语");
setpos(50, 3);
printf("物理");
setpos(55, 3);
printf("化学");
setpos(60, 3);
printf("生物");
setpos(65, 3);
printf("总分");
// 显示每个学生的信息
for (i = 0; i < sum; i++)
showsin(&mn->student[i], i);
setpos(50, 25);
system("pause");
system("cls");
}
// 清空学生信息
void clean(mana mn) {
system("cls");
free(mn->student); // 释放学生数组内存
mn->student = NULL;
mn->capacity = mn->sum = 0; // 重置容量和学生数量
setpos(40, 14);
printf("清空成功");
system("pause");
}
// 交换两个学生的信息
void swap(student p1, student p2) {
struct a2 mn = *p1;
*p1 = *p2;
*p2 = mn;
}
// 未实现的函数占位符
functioncreate(Math)
functioncreate(Chinese)
functioncreate(English)
functioncreate(Physics)
functioncreate(Chemistry)
functioncreate(Organism)
functioncreate(All)
// 选择排序方式并执行
void compare(mana mn) {
system("cls");
setpos(37, 10);
printf("请选择您的排序方式");
// 显示排序选项
setpos(35, 12);
printf("1.语文");
setpos(45, 12);
printf("2.数学");
setpos(35, 14);
printf("3.英语");
setpos(45, 14);
printf("4.物理");
setpos(35, 16);
printf("5.化学");
setpos(45, 16);
printf("6.生物");
setpos(35, 18);
printf("7.学号");
setpos(45, 18);
printf("8.总分");
setpos(40, 20);
int a;
scanf("%d", &a);
// 根据选择执行相应的排序函数
switch (a) {
case 1:Chinesecompare(mn); break;
case 2:Mathcompare(mn); break;
case 3:Englishcompare(mn); break;
case 4:Physicscompare(mn); break;
case 5:Chemistrycompare(mn); break;
case 6:Organismcompare(mn); break;
case 7:stunumcompare(mn); break;
case 8:Allcompare(mn); break;
}
system("cls");
setpos(40, 14);
printf("排序完成,请自行查看");
setpos(40, 15);
system("pause");
}
// 显示指定班级的学生信息
void showClassStudents(mana mn) {
system("cls");
int classNum; // 用户输入的班级号
setpos(30, 10);
printf("请输入要查询的班号: ");
scanf("%d", &classNum);
// 创建新的mana对象用于存储特定班级的学生
mana classMn = (mana)malloc(sizeof(struct a3));
initmana(classMn);
// 遍历原始mana对象,复制符合班级号的学生到新的mana对象
for (int i = 0; i < mn->sum; i++) {
if (mn->student[i].Class == classNum) {
exportcapacity(classMn);
classMn->student[classMn->sum] = mn->student[i];
classMn->sum++;
}
}
if (classMn->sum == 0) {
system("cls");
setpos(30, 10);
printf("该班级无学生记录");
system("pause");
}
else {
compare(classMn);
showall(classMn);
}
// 释放新创建的mana对象内存
free(classMn->student);
free(classMn);
setpos(50, 25);
system("cls");
}
// 程序入口,显示欢迎界面并处理用户选择
void manager(mana mn) {
int choose;
do {
menu(); // 显示主菜单
scanf("%d", &choose);
// 根据用户选择执行相应功能
switch (choose) {
case 1:addstu(mn); break;
case 2:clean(mn); break;
case 3:compare(mn); break;
case 4:showClassStudents(mn); break;
case 5:modifystu(mn); break;
case 6:showall(mn); break;
case 0:break;
}
save(mn);
} while (choose);
}
void save(mana all) {//人数,空间,学生信息
FILE* file = fopen("allinfo.txt", "w");
fprintf(file,"%d ",all->sum);
fprintf(file, "%d ", all->capacity);
fclose(file);
file = fopen("info.txt", "w");//班级 学号 姓名 成绩
student stu=all->student;
int i;
for (i = 0; i < all->sum; i++) {
fprintf(file, "%d ", stu[i].Class);
fprintf(file, "%s ", stu[i].stunum);
fprintf(file, "%s ", stu[i].name);
fprintf(file, "%d %d %d %d %d %d %d ", stu[i].grade->All, stu[i].grade->Chemistry, stu[i].grade->Chinese, stu[i].grade->English, stu[i].grade->Math, stu[i].grade->Organism, stu[i].grade->Physics);
}
fclose(file);
}
void read(mana all) {
FILE* file = fopen("allinfo.txt", "r");
fscanf(file,"%d",&all->sum);
fscanf(file, "%d", &all->capacity);
fclose(file);
all->student = (student)malloc(sizeof(struct a2) * all->sum);
student stu=all->student;
file = fopen("info.txt", "r");
int i;
for (i = 0; i < all->sum; i++) {//班级 学号 姓名 成绩
fscanf(file, "%d", &stu[i].Class);
fscanf(file, "%s", stu[i].stunum);
fscanf(file, "%s", stu[i].name);
stu[i].grade = (grade)malloc(sizeof(struct a1));
fscanf(file, "%d%d%d%d%d%d%d", &stu[i].grade->All, &stu[i].grade->Chemistry, &stu[i].grade->Chinese, &stu[i].grade->English, &stu[i].grade->Math, &stu[i].grade->Organism, &stu[i].grade->Physics);
}
}
void regist() {
system("cls");
FILE* file = fopen("account number.txt", "a");
acco m;
setpos(40, 12);
printf("请输入您的账号:");
scanf("%s", m.account);
system("cls");
setpos(40, 12);
printf("请输入您的密码:");
scanf("%s", m.password);
system("cls");
setpos(35, 12);
printf("请选择您的用户类型:1.管理员 2.老师 3.学生");
setpos(50, 13);
scanf("%d", &m.kind);
system("cls");
setpos(50, 14);
printf("请输入您的学号/工号:");
scanf("%s", &m.stunum);
system("cls");
setpos(40, 12);
printf("恭喜您创建成功!");
setpos(40, 13);
fprintf(file, "%s %s %d %s\n",m.account,m.password,m.kind,m.stunum);
fclose(file);
system("pause");
}
int identify(int a) {
system("cls");
setpos(40, 12);
printf("请输入您的账号:");
char ac[20],nu[20];
scanf("%s", ac);
setpos(40, 13);
printf("请输入您的密码:");
scanf("%s", nu);
system("cls");
FILE* file = fopen("account number.txt","r");
char ab[20], bc[20],num[20];
int kind,flag=0;
while (fscanf(file, "%s%s%d%s", ab, bc, &kind,num) != EOF) {
if (strcmp(ac, ab) || strcmp(nu, bc))
continue;
flag = 1;
break;
}
system("cls");
if (flag) {
setpos(40, 12);
printf("欢迎使用本系统!");
setpos(40, 13);
system("pause");
return 1;
}
setpos(40, 12);
printf("账号密码错误,请重新输入");
setpos(40, 13);
system("pause");
return 0;
}
void enter() {
welcome();
int a;
mana mn = (mana)malloc(sizeof(struct a3));
initmana(mn); // 初始化管理结构
read(mn);
while (1) {
system("cls");
setpos(40, 12);
printf("请选择登陆方式:");
setpos(29, 13);
printf("1.管理员 2.老师 3.学生 4.退出 5.注册账号");
setpos(40, 15);
scanf("%d", &a);
if (a == 4)
break;
if (a == 5) {
regist();
continue;
}
if (a != 1 && a != 2 && a != 3) {
system("cls");
setpos(40, 12);
printf("选择错误");
setpos(38, 13);
system("pause");
continue;
}
if (!identify(a))
continue;
switch (a) {
case 1:manager(mn); break;
case 2:teacher(mn); break;
case 3:stu(mn); break;
default:break;
}
}
save(mn);
clear(mn);
}
void clear(mana all) {
int i;
for (i = 0; i < all->sum; i++)
free(all->student[i].grade);
free(all->student);
free(all);
}
void teacher(mana all) {
system("cls");
while (1) {
setpos(40, 12);
printf("是否查看班级信息:1.是 0.否");
setpos(45, 13);
int a;
scanf("%d", &a);
if (a)
showClassStudents(all);
else
break;
}
}
void stu(mana all) {
FILE* file = fopen("account number.txt", "r");
int i;
char stunum[20];
flag:system("cls");
setpos(40, 12);
printf("请输入您的学号(输入0则退出):");
scanf("%s", stunum);
system("cls");
if (!strcmp("0", stunum))
return;
for (i = 0; i < all->sum; i++) {
if (strcmp(stunum, all->student[i].stunum))
continue;
break;
}
if (i == all->sum) {
system("cls");
setpos(40, 12);
printf("学号不存在");
setpos(40, 13);
system("pause");
goto flag;
}
setpos(20, 3);
printf("班级");
setpos(25, 3);
printf("姓名");
setpos(30, 3);
printf("学号");
setpos(35, 3);
printf("语文");
setpos(40, 3);
printf("数学");
setpos(45, 3);
printf("英语");
setpos(50, 3);
printf("物理");
setpos(55, 3);
printf("化学");
setpos(60, 3);
printf("生物");
setpos(65, 3);
printf("总分");
showsin(&all->student[i], 0);
setpos(40, 12);
system("pause");
}