1. 设计要求
2. 大致逻辑以及主要结构体的定义
3. 程序说明
4. 源码
#define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<String.h>
#include<time.h>
#include<Windows.h>
#define USERLEN 20 //用户长度
#define PASSLEN 20 //密码长度
#define KEYLEN 3 //标识符长度
#define CLASSLEN 20 //班级名长度
#define STRCHLEN 10 //遍历打印菜单长度
#define BLSTRLEN 3 //遍历打印数组长度
#define ARRLEN 3 //数组初始化大小
#define ADDLEN 5 //数组每次增容大小
//用户
typedef struct user {
char user[USERLEN]; //账户
char pass[PASSLEN]; //密码
char admin[KEYLEN]; //管理员
}user;
//用户数组
typedef struct userArr {
user* ur; //用户数组
int index; //数组当前下标
int maxIndex; //数组最大容量
}urArr;
//学生
typedef struct students {
int id; //学号
char stuName[USERLEN]; //姓名
char className[CLASSLEN]; //班级
double c; //C成绩
double java; //Java成绩
}students;
//学生数组
typedef struct stuArr {
students* sr; //学生数组
int index; //数组当前下标
int maxIndex; //数组最大容量
}stuArr;
//班级
typedef struct studentClass {
char headName[USERLEN]; //班级班主任
char ClassName[CLASSLEN]; //班级
char cTeacherName[USERLEN]; //C语言老师
char javaTeacherName[USERLEN]; //Java老师
}studentClass;
//班级数组
typedef struct classArray {
studentClass* cr; //班级数组
int index; //数组当前下标
int maxIndex; //数组最大容量
}claArr;
//遍历菜单
typedef struct pl {
char ch[STRCHLEN]; //菜单内容
char fh[STRCHLEN]; //指针
}pl;
//菜单数组
typedef struct plArr {
pl o[BLSTRLEN]; //菜单数组
int i; //当前下标
}pArr;
//初始化用户数组
void iniUserArr(urArr* pu);
//用户数组增容
void addUserMemory(urArr* pu);
//读取用户文件
void readUserFile(urArr* pu);
//写入用户文件
void writeUserFile(urArr* pu);
//初始化学生数组
void iniStuArr(stuArr* ps);
//学生数组增容
void addStuMemory(stuArr* ps);
//读取学生文件
void readStuFile(stuArr* ps);
//写入学生文件
void writeStuFile(stuArr* ps);
//初始化班级数组
void iniClassArr(claArr* pc);
//班级数组增容
void addClassMemory(claArr* pc);
//读取班级文件
void readClassFile(claArr* pc);
//写入班级文件
void writeClassFile(claArr* pc);
//加载页面
void indexPage();
//选择函数
void choicePage(urArr* pu, stuArr* ps, claArr* pc, pArr* po);
//向上移动
void moveup(pArr* po);
//向下移动
void movedown(pArr* po);
//遍历打印结构体数组
void see(pArr* po);
//初始化遍历结构体数组
void begin(pArr* po);
//打印班级
void printClass(claArr* pc);
//登录
void signIn(urArr* pu, stuArr* ps, claArr* pc);
//管理员
void adminPage(urArr* pu, stuArr* ps, claArr* pc);
//寻找班级
int ergClass(claArr* pc, char className[CLASSLEN]);
//班级操作
void classOper(claArr* pc, char className[CLASSLEN]);
//双重身份用户选择
void doubleUser(urArr* pu, stuArr* ps, claArr* pc, int ku, int kc);
//打印学生
void seeStu(urArr* pu, stuArr* ps, claArr* pc, int ku, int kc);
//班主任登录
void headSign(urArr* pu, stuArr* ps, claArr* pc, int ku, int kc);
//教师登录
void teacherSign(urArr* pu, stuArr* ps, claArr* pc, int ku, int kc);
//选择跳转
void skip(urArr* pu, stuArr* ps, claArr* pc, pArr* po);
//选择学生
int choStu(urArr* pu, stuArr* ps, claArr* pc, int ku, int kc);
int main() {
urArr uA; //用户数组变量
stuArr sA; //学生数组变量
claArr cA; //班级数组变量
pArr pA; //菜单数组变量
//初始化数组
iniUserArr(&uA);
iniStuArr(&sA);
iniClassArr(&cA);
indexPage();
choicePage(&uA, &sA, &cA, &pA);
return 0;
}
//管理员
void adminPage(urArr* pu, stuArr* ps, claArr* pc) {
int a = 0;
int key = 0;
char className[CLASSLEN];
while (1) {
system("cls");
printf("1.添加用户\n2.添加班级\n3.退出系统\n请选择你的操作>");
scanf("%d", &a);
switch (a) {
case 1:
printf("请输入账户>");
scanf("%s", pu->ur[pu->index].user);
printf("请输入密码>");
scanf("%s", pu->ur[pu->index].pass);
strcpy(pu->ur[pu->index++].admin, "否");
addUserMemory(pu);
writeUserFile(pu);
system("cls");
printf("添加成功");
system("pause");
break;
case 2:
system("cls");
printClass(pc);
printf("请输入班级名>");
scanf("%s", className);
if ((key = ergClass(pc, className)) == -1) {
classOper(pc, className);
pc->index++;
addClassMemory(pc);
writeClassFile(pc);
}
else {
classOper(pc, className);
writeClassFile(pc);
}
break;
case 3:exit(0); break;
default:printf("选择错误!"); break;
}
}
}
//班级操作
void classOper(claArr* pc, char className[CLASSLEN]) {
strcpy(pc->cr[pc->index].ClassName, className);
printf("请输入班主任>");
scanf("%s", pc->cr[pc->index].headName);
printf("请输入C语言任课老师>");
scanf("%s", pc->cr[pc->index].cTeacherName);
printf("请输入Java任课老师>");
scanf("%s", pc->cr[pc->index].javaTeacherName);
}
//寻找班级
int ergClass(claArr* pc, char className[CLASSLEN]) {
int i = 0;
for (i = 0; i < pc->index; ++i) {
if (strcmp(pc->cr[i].ClassName, className) == 0) {
return i;
}
}
return -1;
}
//打印班级
void printClass(claArr* pc) {
int i = 0;
for (i = 0; i < pc->index; ++i) {
printf("班级:%s 班主任:%s C语言老师:%s Java老师:%s\n", pc->cr[i].ClassName, pc->cr[i].headName, pc->cr[i].cTeacherName, pc->cr[i].javaTeacherName);
}
}
//打印学生
void seeStu(urArr* pu, stuArr* ps, claArr* pc, int ku, int kc) {
int i = 0;
for (i = 0; i < ps->index; ++i) {
if (strcmp(ps->sr[i].className, pc->cr[kc].ClassName) == 0) {
printf("学号:%d 姓名:%s C语言成绩:%g Java成绩:%g\n", ps->sr[i].id, ps->sr[i].stuName, ps->sr[i].c, ps->sr[i].java);
}
}
}
//班主任登录
void headSign(urArr* pu, stuArr* ps, claArr* pc, int ku, int kc) {
int a = 0, i = 0, j = 0, z = 1;
FILE* fp;
while (z) {
printf("您现在操作的班级是:%s\n1.录入班级学生信息\n2.查看本班学生成绩\n3.导出学生信息\n4.退出\n请输入要进行的操作>", pc->cr[kc].ClassName);
scanf("%d", &a);
switch (a) {
case 1:
printf("请输入学生姓名>");
scanf("%s", ps->sr[ps->index].stuName);
ps->sr[ps->index].id = ps->index + 1;
strcpy(ps->sr[ps->index].className, pc->cr[kc].ClassName);
ps->sr[ps->index].c = 00.00;
ps->sr[ps->index++].java = 00.00;
addStuMemory(ps);
writeStuFile(ps);
printf("添加成功\n");
system("pause");
system("cls");
break;
case 2:
seeStu(pu, ps, pc, ku, kc);
system("pause");
system("cls");
break;
case 3:
fp = fopen("D:\\学生信息.txt", "wt");
for (i = 0; i < ps->index; ++i) {
if (strcmp(ps->sr[i].className, pc->cr[kc].ClassName) == 0) {
fprintf(fp, "学号:%d 姓名:%s 班级:%s C语言成绩:%lf Java成绩:%lf\n", ps->sr[i].id, ps->sr[i].stuName, ps->sr[i].className, ps->sr[i].c, ps->sr[i].java);
}
}
fclose(fp);
fp = NULL;
printf("导出成功,请前往D盘查看!文件名学生信息.txt\n");
system("pause");
system("cls");
break;
case 4:z = 0; system("cls"); break;
default:printf("输入错误!"); break;
}
}
}
//教师登录
void teacherSign(urArr* pu, stuArr* ps, claArr* pc, int ku, int kc) {
int a = 0, i = 0, j = 0, z = 1, ks = -1;
while (z) {
printf("您现在操作的是%s班级\n1.录入学生考试成绩\n2.修改学生考试成绩\n3.查看学生考试成绩\n4.退出系统\n请输入你的操作>", pc->cr[kc].ClassName);
scanf("%d", &a);
switch (a) {
case 1:
if ((ks = choStu(pu, ps, pc, ku, kc)) != -1) {
if (strcmp(pu->ur[ku].user, pc->cr[kc].cTeacherName) == 0) {
printf("请输入 %s 的成绩>", ps->sr[ks].stuName);
scanf("%lf", &ps->sr[ks].c);
printf("录入成功!");
}
else if (strcmp(pu->ur[ku].user, pc->cr[kc].javaTeacherName) == 0) {
printf("请输入 %s 的成绩>", ps->sr[ks].stuName);
scanf("%lf", &ps->sr[ks].java);
printf("录入成功!");
}
}
else {
printf("不存在该学生!");
}
system("pause");
system("cls");
break;
case 2:
if ((ks = choStu(pu, ps, pc, ku, kc)) != -1) {
if (strcmp(pu->ur[ku].user, pc->cr[kc].cTeacherName) == 0) { //判断教师属于哪个权限
printf("请输入 %s 的成绩>", ps->sr[ks].stuName);
scanf("%lf", &ps->sr[ks].c);
printf("修改成功!");
}
else if (strcmp(pu->ur[ku].user, pc->cr[kc].javaTeacherName) == 0) {
printf("请输入 %s 的成绩>", ps->sr[ks].stuName);
scanf("%lf", &ps->sr[ks].java);
printf("修改成功!");
}
}
else {
printf("不存在该学生!");
}
system("pause");
system("cls");
break;
case 3:
if (strcmp(pc->cr[kc].cTeacherName, pu->ur[ku].user) == 0) {
for (i = 0; i < ps->index; ++i) {
if (strcmp(ps->sr[i].className, pc->cr[kc].ClassName) == 0) {
printf("学号:%d 姓名:%s C语言成绩:%g\n", ps->sr[i].id, ps->sr[i].stuName, ps->sr[i].c);
}
}
}
else if (strcmp(pc->cr[kc].javaTeacherName, pu->ur[ku].user) == 0) {
for (i = 0; i < ps->index; ++i) {
if (strcmp(ps->sr[i].className, pc->cr[kc].ClassName) == 0) {
printf("学号:%d 姓名:%s Java语言成绩:%g\n", ps->sr[i].id, ps->sr[i].stuName, ps->sr[i].java);
}
}
}
else {
printf("抱歉你无权对此班级进行操作");
}
system("pause");
system("cls");
break;
case 4:z = 0; system("cls"); break;
default:printf("输入错误!"); break;
}
writeStuFile(ps);
}
}
//选择学生
int choStu(urArr* pu, stuArr* ps, claArr* pc, int ku, int kc) {
int stuId;
int i = 0;
printf("请输入学生学号>");
scanf("%d", &stuId);
for (i = 0; i < ps->index; ++i) {
if (ps->sr[i].id == stuId && strcmp(ps->sr[i].className, pc->cr[kc].ClassName) == 0) {
return i;
}
}
return -1;
}
//双重身份用户选择
void doubleUser(urArr* pu, stuArr* ps, claArr* pc, int ku, int kc) {
int a = 0, i = 0;
while (1) {
printClass(pc);
printf("1.班主任\n2.教师\n3.退出\n请选择你要进行的操作>");
scanf("%d", &a);
switch (a) {
case 1:system("cls"); headSign(pu, ps, pc, ku, kc); break;
case 2:system("cls"); teacherSign(pu, ps, pc, ku, kc); break;
case 3:system("cls"); exit(0); break;
default:system("cls"); printf("选择错误!"); system("pause"); break;
}
}
}
//登录
void signIn(urArr* pu, stuArr* ps, claArr* pc) {
char user[USERLEN], pass[PASSLEN], className[CLASSLEN];
int i = 0, j = 0;
printf("请输入用户名>");
scanf("%s", user);
printf("请输入密码>");
scanf("%s", pass);
for (i = 0; i < pu->index; ++i) {
if (strcmp(pu->ur[i].user, user) == 0 && strcmp(pu->ur[i].pass, pass) == 0) {
if (strcmp(pu->ur[i].admin, "是") == 0) {
adminPage(pu, ps, pc);
}
else {
while (1) {
system("cls");
printClass(pc);
printf("请输入你要操作的班级>");
scanf("%s", className);
for (j = 0; j < pc->index; ++j) {
if (strcmp(pc->cr[j].ClassName, className) == 0) {
if (strcmp(pc->cr[j].headName, pu->ur[i].user) == 0 && strcmp(pc->cr[j].cTeacherName, pu->ur[i].user) == 0 || strcmp(pc->cr[j].javaTeacherName, pu->ur[i].user) == 0) {
system("cls");
doubleUser(pu, ps, pc, i, j);
break;
}
else if (strcmp(pc->cr[j].cTeacherName, pu->ur[i].user) == 0 || strcmp(pc->cr[j].javaTeacherName, pu->ur[i].user) == 0) {
system("cls");
teacherSign(pu, ps, pc, i, j);
break;
}
else if (strcmp(pc->cr[j].headName, pu->ur[i].user) == 0) {
system("cls");
headSign(pu, ps, pc, i, j);
break;
}
else {
system("cls");
printf("你无权操作该班级");
system("pause");
break;
}
}
}
if (j == pc->index) {
printf("不存在该班级,请联系管理员添加!");
system("pause");
}
}
}
}
//break;
}
if (i == pu->index) {
printf("账号密码错误!");
}
}
//初始化遍历结构体数组
void begin(pArr* po) {
int i = 0;
strcpy(po->o[0].ch, "教师登录");
strcpy(po->o[1].ch, "成绩查询");
strcpy(po->o[2].ch, "退出系统");
strcpy(po->o[0].fh, "<--"); //箭头
for (i = 1; i < 3; ++i) {
strcpy(po->o[i].fh, " "); //箭头
}
}
//遍历打印结构体数组
void see(pArr* po) {
int j;
system("cls");
for (j = 0; j < BLSTRLEN; j++)
{
printf("\t\t\t\t%s%s\n", po->o[j].ch, po->o[j].fh);
}
}
//向上移动
void moveup(pArr* po) {
if (po->i <= 2 && po->i > 0)
{
strcpy(po->o[po->i].fh, " ");
strcpy(po->o[--(po->i)].fh, "<--");
}
}
//向下移动
void movedown(pArr* po) {
if (po->i >= 0 && po->i < 2)
{
strcpy(po->o[po->i].fh, " ");
strcpy(po->o[++(po->i)].fh, "<--");
}
}
//学生查询成绩
void stuQuery(stuArr* ps) {
int stuId = 0, i = 0;
system("cls");
printf("请输入学号>");
scanf("%d", &stuId);
for (i = 0; i < ps->index; ++i) {
if (ps->sr[i].id == stuId) {
printf("学号:%d 姓名:%s 班级:%s C语言成绩:%g Java成绩:%g\n", ps->sr[i].id, ps->sr[i].stuName, ps->sr[i].className, ps->sr[i].c, ps->sr[i].java);
break;
}
}
}
//选择函数
void choicePage(urArr* pu, stuArr* ps, claArr* pc, pArr* po) {
po->i = 0;
begin(po);
see(po);
while (1)
{
switch (getch())
{
case 72:
moveup(po);
see(po);
break;
case 80:
movedown(po);
see(po);
break;
case 13:
system("cls");
skip(pu, ps, pc, po);
break;
}
see(po);
}
}
//选择跳转
void skip(urArr* pu, stuArr* ps, claArr* pc, pArr* po) {
switch (po->i) {
case 0:
signIn(pu, ps, pc);
system("pause");
break;
case 1:
stuQuery(ps);
system("pause");
break;
case 2:
exit(0);
break;
}
system("cls");
}
//加载页面
void indexPage() {
int i = 0;
//■□
printf("\n\n\n\n\n\n\n\n\n\n\n\t\t\t\t■■■■■■■■■■");
printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
for (i = 0; i < 10; ++i) {
Sleep(350);
printf("□");
}
system("cls");
}
//写入班级文件
void writeClassFile(claArr* pc) {
int i = 0;
FILE* fp = fopen("D:\\class.txt", "wt");
for (i = 0; i < pc->index; ++i) {
fprintf(fp, "班级:%s 班主任:%s C语言老师:%s Java老师:%s\n", pc->cr[i].ClassName, pc->cr[i].headName, pc->cr[i].cTeacherName, pc->cr[i].javaTeacherName);
}
fclose(fp);
fp = NULL;
}
//读取班级文件
void readClassFile(claArr* pc) {
FILE* fp = fopen("D:\\class.txt", "rt");
if (fp == NULL) {
fp = fopen("D:\\class.txt", "wt");
strcpy(pc->cr[pc->index].ClassName, "软件2102");
strcpy(pc->cr[pc->index].headName, "c9noo");
strcpy(pc->cr[pc->index].cTeacherName, "test");
strcpy(pc->cr[pc->index++].javaTeacherName, "c9noo");
}
else {
while (fscanf(fp, "班级:%s 班主任:%s C语言老师:%s Java老师:%s\n", pc->cr[pc->index].ClassName, pc->cr[pc->index].headName, pc->cr[pc->index].cTeacherName, pc->cr[pc->index].javaTeacherName) != EOF) {
pc->index++;
addClassMemory(pc);
}
}
fclose(fp);
fp = NULL;
writeClassFile(pc);
}
//班级数组增容
void addClassMemory(claArr* pc) {
if (pc->index == pc->maxIndex) {
studentClass* Q = realloc(pc->cr, (pc->maxIndex + ADDLEN) * sizeof(studentClass));
if (Q == NULL) {
printf("用户数组增容失败!");
}
else {
pc->cr = Q;
pc->maxIndex += ADDLEN;
}
Q = NULL;
}
}
//初始化班级数组
void iniClassArr(claArr* pc) {
studentClass* Q = (studentClass*)malloc(ARRLEN * sizeof(studentClass));
if (Q == NULL) {
printf("用户数组创建失败!");
}
else {
pc->cr = Q;
memset(pc->cr, 0, sizeof(pc->cr));
pc->index = 0;
pc->maxIndex = ARRLEN;
}
Q = NULL;
readClassFile(pc);
}
//写入学生文件
void writeStuFile(stuArr* ps) {
int i = 0;
FILE* fp = fopen("D:\\student.txt", "wt");
for (i = 0; i < ps->index; ++i) {
fprintf(fp, "学号:%d 姓名:%s 班级:%s C语言成绩:%lf Java成绩:%lf\n", ps->sr[i].id, ps->sr[i].stuName, ps->sr[i].className, ps->sr[i].c, ps->sr[i].java);
}
fclose(fp);
fp = NULL;
}
//学生数组增容
void addStuMemory(stuArr* ps) {
if (ps->index == ps->maxIndex) {
students* Q = realloc(ps->sr, (ps->maxIndex + ADDLEN) * sizeof(students));
if (Q == NULL) {
printf("用户数组增容失败!");
}
else {
ps->sr = Q;
ps->maxIndex += ADDLEN;
}
Q = NULL;
}
}
//读取学生文件
void readStuFile(stuArr* ps) {
FILE* fp = fopen("D:\\student.txt", "rt");
if (fp == NULL) {
fp = fopen("D:\\student.txt", "wt");
ps->sr[ps->index].id = 10086;
strcpy(ps->sr[ps->index].stuName, "李金蛋");
strcpy(ps->sr[ps->index].className, "软件2102");
ps->sr[ps->index].c = 32.14;
ps->sr[ps->index].java = 43.23;
ps->index++;
}
else {
while (fscanf(fp, "学号:%d 姓名:%s 班级:%s C语言成绩:%lf Java成绩:%lf\n", &ps->sr[ps->index].id, ps->sr[ps->index].stuName, ps->sr[ps->index].className, &ps->sr[ps->index].c, &ps->sr[ps->index].java) != EOF) {
ps->index++;
addStuMemory(ps);
}
}
fclose(fp);
fp = NULL;
writeStuFile(ps);
}
//初始化学生数组
void iniStuArr(stuArr* ps) {
students* Q = (students*)malloc(ARRLEN * sizeof(students));
if (Q == NULL) {
printf("用户数组创建失败!");
}
else {
ps->sr = Q;
memset(ps->sr, 0, sizeof(ps->sr));
ps->index = 0;
ps->maxIndex = ARRLEN;
}
Q = NULL;
readStuFile(ps);
}
//用户数组增容
void addUserMemory(urArr* pu) {
if (pu->index == pu->maxIndex) {
user* Q = realloc(pu->ur, (pu->maxIndex + ADDLEN) * sizeof(user));
if (Q == NULL) {
printf("用户数组增容失败!");
}
else {
pu->ur = Q;
pu->maxIndex += ADDLEN;
}
Q = NULL;
}
}
//写入用户文件
void writeUserFile(urArr* pu) {
int i = 0;
FILE* fp = fopen("D:\\user.txt", "wt");
for (i = 0; i < pu->index; ++i) {
fprintf(fp, "账号:%s 密码:%s 管理员:%s\n", pu->ur[i].user, pu->ur[i].pass, pu->ur[i].admin);
}
fclose(fp);
fp = NULL;
}
//读取用户文件
void readUserFile(urArr* pu) {
FILE* fp = fopen("D:\\user.txt", "rt");
if (fp == NULL) {
fp = fopen("D:\\user.txt", "wt");
//当不存在文件的时候,添加
strcpy(pu->ur[pu->index].user, "admin");
strcpy(pu->ur[pu->index].pass, "123456");
strcpy(pu->ur[pu->index++].admin, "是");
strcpy(pu->ur[pu->index].user, "c9noo");
strcpy(pu->ur[pu->index].pass, "123456");
strcpy(pu->ur[pu->index++].admin, "否");
strcpy(pu->ur[pu->index].user, "test");
strcpy(pu->ur[pu->index].pass, "123456");
strcpy(pu->ur[pu->index++].admin, "否");
}
else {
while (fscanf(fp, "账号:%s 密码:%s 管理员:%s\n", pu->ur[pu->index].user, pu->ur[pu->index].pass, pu->ur[pu->index].admin) != EOF) {
pu->index++;
addUserMemory(pu);
}
}
fclose(fp);
fp = NULL;
writeUserFile(pu);
}
//初始化用户数组
void iniUserArr(urArr* pu) {
user* Q = (user*)malloc(ARRLEN * sizeof(user));
if (Q == NULL) {
printf("用户数组创建失败!");
}
else {
pu->ur = Q;
memset(pu->ur, 0, sizeof(pu->ur));
pu->index = 0;
pu->maxIndex = ARRLEN;
}
Q = NULL;
readUserFile(pu);
}