项目结构:
exam.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#include <string.h>
#define QLEN sizeof(struct question)
#define SLEN sizeof(struct student)
void judge(struct question* que, struct student* stu)//评判答案是否正确函数
{
struct student* p_stu = stu;
struct question* p_que = que;
char filename[40]; // 文件名
char answer[20];
while (p_stu != NULL) {
sprintf(filename, "Answers/%s%s-%s.txt", p_stu->subject, p_stu->stuclass, p_stu->name);
FILE* fp_l = fopen(filename, "r");
if (fp_l == NULL) {
perror("无法读取答案");
system("pause");
exit(1); // 处理文件打开失败的情况
}
p_que = que; // 回到题目链表头
while (p_que != NULL)
{
fscanf(fp_l, "%99[^\n]\n", answer);
if (strncmp(p_que->result, answer, strlen(p_que->result)) == 0)
{
p_stu->scores += p_que->score;
}
p_que = p_que->next;
}
printf("已批改完%s的成绩\n", p_stu->name);
fclose(fp_l);
p_stu = p_stu->next;
}
}
void* record(struct student* p, char* answer)//录入学生所写题目答案函数
{
char filename[40]; // 文件名
struct student* head = NULL;
head = p;
sprintf(filename, "Answers/%s%s-%s.txt", head->subject, head->stuclass, head->name);
// strcat(head->result,answer);
FILE* fp_wr = fopen(filename, "a");
if (fp_wr == NULL) {
perror("无法存储答案");
exit(1); // 处理文件打开失败的情况
}
fprintf(fp_wr, "%s\n", answer);
fclose(fp_wr);
}
headfile.h
#pragma once
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
void detectFileExistence() { //检测必要文件
printf("检测必要文件是否已创建……");
char filename[100][100];
strcpy(filename[0], "stu.txt");
strcpy(filename[1], "stu1.txt");
strcpy(filename[2], "teachers.txt");
strcpy(filename[3], "timu.txt");
for (int i = 0; i <= 3; i++) {
FILE* file = fopen(filename[i], "r");
if (file == NULL) {
// 文件不存在,创建文件
file = fopen(filename[i], "w");
if (file == NULL) {
fprintf(stderr, "无法创建文件 %s\n", filename[i]);
exit(1); // 处理文件创建失败的情况
}
printf("检测到 %s 文件不存在,已创建!", filename[i]);
fclose(file);
}
else {
fclose(file);
}
}
}
m.h
#pragma once
#include <time.h>
#include <conio.h>
#include <iostream>
#include <graphics.h>
#define MAXSTAR 300 // 星星总数
struct STAR
{
double x;
int y;
double step;
int color;
};
STAR star[MAXSTAR];
// 初始化星星
void InitStar(int i)
{
star[i].x = 0;
star[i].y = rand() % 880;
star[i].step = (rand() % 5000) / 1000.0 + 1;
star[i].color = (int)(star[i].step * 255 / 6.0 + 0.1); // 速度越快,颜色越亮
star[i].color = RGB(star[i].color, star[i].color, star[i].color);
}
// 移动星星
void MoveStar(int i)
{
// 擦掉原来的星星
putpixel((int)star[i].x, star[i].y, 0);
// 计算新位置
star[i].x += star[i].step;
if (star[i].x > 1080) InitStar(i);
// 画新星星
putpixel((int)star[i].x, star[i].y, star[i].color);
}
int menu1()//注册登录菜单
{
initgraph(1080, 880);
settextstyle(25, 20, _T("Courier"));
ExMessage m;
releasecapture();
int flag = 1;
while (flag)
{
rectangle(100, 100, 980, 780);
rectangle(95, 95, 975, 775);
rectangle(300, 330, 500, 370);
rectangle(300, 380, 500, 420);
rectangle(300, 430, 500, 470);
rectangle(300, 480, 500, 520);
outtextxy(340, 300, _T("请选择您的操作: "));
outtextxy(335, 350, _T("1.登录账户"));
outtextxy(335, 400, _T("2.注册账户"));
outtextxy(335, 450, _T("3.找回密码"));
outtextxy(335, 500, _T("4.退出系统"));
m = getmessage(EX_MOUSE);
//peekmessage(&m, EX_MOUSE, true);
switch (m.message)
{
case WM_MOUSEMOVE:
continue;
case WM_LBUTTONDOWN:
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 330 && m.y <= 370) {
flag = 0;
closegraph();
return 1;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 380 && m.y <= 420) {
flag = 0;
closegraph();
return 2;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 430 && m.y <= 470) {
flag = 0;
closegraph();
return 3;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 480 && m.y <= 520) {
flag = 0;
closegraph();
return 4;
}
break;
default:
break;
}
}
closegraph();
return 0;
}
int menu2()//学生操作界面
{
initgraph(1080, 880);
settextstyle(25, 20, _T("Courier"));
ExMessage m;
releasecapture();
int flag = 1;
while (flag)
{
rectangle(100, 100, 980, 780);
rectangle(95, 95, 975, 775);
rectangle(300, 330, 500, 370);
rectangle(300, 380, 500, 420);
rectangle(300, 430, 500, 470);
outtextxy(340, 300, _T("请选择您的操作: "));
outtextxy(335, 350, _T("1.开始答题"));
outtextxy(335, 400, _T("2.查看个人信息"));
outtextxy(335, 450, _T("3.退出"));
m = getmessage(EX_MOUSE);
//peekmessage(&m, EX_MOUSE, true);
switch (m.message)
{
case WM_MOUSEMOVE:
continue;
case WM_LBUTTONDOWN:
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 330 && m.y <= 370) {
flag = 0;
closegraph();
return 1;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 380 && m.y <= 420) {
flag = 0;
closegraph();
return 2;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 430 && m.y <= 470) {
flag = 0;
closegraph();
return 3;
}
break;
default:
break;
}
}
closegraph();
return 0;
}
int menu3()//老师操作界面
{
initgraph(1080, 880);
settextstyle(25, 20, _T("Courier"));
ExMessage m;
releasecapture();
int flag = 1;
while (flag)
{
rectangle(100, 100, 980, 780);
rectangle(95, 95, 975, 775);
rectangle(300, 330, 500, 370);
rectangle(300, 380, 500, 420);
rectangle(300, 430, 500, 470);
rectangle(300, 480, 530, 520);
rectangle(300, 530, 500, 570);
rectangle(300, 580, 530, 620);
rectangle(300, 630, 500, 670);
rectangle(300, 680, 500, 720);
outtextxy(340, 300, _T("请选择您的操作: "));
outtextxy(335, 350, _T("1.录入题目"));
outtextxy(335, 400, _T("2.计算成绩"));
outtextxy(335, 450, _T("3.显示成绩"));
outtextxy(335, 500, _T("4.查询学生成绩"));
outtextxy(335, 550, _T("5.删除学生"));
outtextxy(335, 600, _T("6.统计学生成绩"));
outtextxy(335, 650, _T("7.排序"));
outtextxy(335, 700, _T("8.退出"));
m = getmessage(EX_MOUSE);
//peekmessage(&m, EX_MOUSE, true);
switch (m.message)
{
case WM_MOUSEMOVE:
continue;
case WM_LBUTTONDOWN:
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 330 && m.y <= 370) {
flag = 0;
closegraph();
return 1;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 380 && m.y <= 420) {
flag = 0;
closegraph();
return 2;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 430 && m.y <= 470) {
flag = 0;
closegraph();
return 3;
}
if (m.lbutton && m.x >= 300 && m.x <= 530 && m.y >= 480 && m.y <= 520) {
flag = 0;
closegraph();
return 4;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 530 && m.y <= 570) {
flag = 0;
closegraph();
return 5;
}
if (m.lbutton && m.x >= 300 && m.x <= 530 && m.y >= 580 && m.y <= 620) {
flag = 0;
closegraph();
return 6;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 630 && m.y <= 670) {
flag = 0;
closegraph();
return 7;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 680 && m.y <= 720) {
flag = 0;
closegraph();
return 8;
}
break;
default:
break;
}
}
closegraph();
return 0;
}
int menu4(int i)//注册&&登录
{
if (i == 1)
{
initgraph(1080, 880);
settextstyle(25, 20, _T("Courier"));
ExMessage m;
releasecapture();
int flag = 1;
while (flag)
{
rectangle(100, 100, 980, 780);
rectangle(95, 95, 975, 775);
rectangle(300, 330, 500, 370);
rectangle(300, 380, 500, 420);
rectangle(300, 430, 500, 470);
outtextxy(340, 300, _T("请选择您要注册的账户类型: "));
outtextxy(335, 350, _T("1.教师账户"));
outtextxy(335, 400, _T("2.学生账户"));
outtextxy(335, 450, _T("3.返回上级"));
m = getmessage(EX_MOUSE);
//peekmessage(&m, EX_MOUSE, true);
switch (m.message)
{
case WM_MOUSEMOVE:
continue;
case WM_LBUTTONDOWN:
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 330 && m.y <= 370) {
flag = 0;
closegraph();
return 1;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 380 && m.y <= 420) {
flag = 0;
closegraph();
return 2;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 430 && m.y <= 470) {
flag = 0;
closegraph();
return 3;
}
break;
default:
break;
}
}
closegraph();
return 0;
}
else if (i == 2)
{
initgraph(1080, 880);
settextstyle(25, 20, _T("Courier"));
ExMessage m;
releasecapture();
int flag = 1;
while (flag)
{
rectangle(100, 100, 980, 780);
rectangle(95, 95, 975, 775);
rectangle(300, 330, 500, 370);
rectangle(300, 380, 500, 420);
rectangle(300, 430, 500, 470);
outtextxy(340, 300, _T("请选择您要登录的账户类型: "));
outtextxy(335, 350, _T("1.教师账户"));
outtextxy(335, 400, _T("2.学生账户"));
outtextxy(335, 450, _T("3.返回上级"));
m = getmessage(EX_MOUSE);
//peekmessage(&m, EX_MOUSE, true);
switch (m.message)
{
case WM_MOUSEMOVE:
continue;
case WM_LBUTTONDOWN:
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 330 && m.y <= 370) {
flag = 0;
closegraph();
return 1;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 380 && m.y <= 420) {
flag = 0;
closegraph();
return 2;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 430 && m.y <= 470) {
flag = 0;
closegraph();
return 3;
}
break;
default:
break;
}
}
closegraph();
return 0;
}
}
int menu5()//统计菜单
{
initgraph(1080, 880);
settextstyle(25, 20, _T("Courier"));
ExMessage m;
releasecapture();
int flag = 1;
while (flag)
{
rectangle(100, 100, 980, 780);
rectangle(95, 95, 975, 775);
rectangle(300, 330, 500, 370);
rectangle(300, 380, 500, 420);
rectangle(300, 430, 500, 470);
outtextxy(340, 300, _T("请选择您的操作: "));
outtextxy(335, 350, _T("1.全统计"));
outtextxy(335, 400, _T("2.条件统计"));
outtextxy(335, 450, _T("3.退出"));
m = getmessage(EX_MOUSE);
//peekmessage(&m, EX_MOUSE, true);
switch (m.message)
{
case WM_MOUSEMOVE:
continue;
case WM_LBUTTONDOWN:
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 330 && m.y <= 370) {
flag = 0;
closegraph();
return 1;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 380 && m.y <= 420) {
flag = 0;
closegraph();
return 2;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 430 && m.y <= 470) {
flag = 0;
closegraph();
return 3;
}
break;
default:
break;
}
}
closegraph();
return 0;
}
int menu6()//第二级统计菜单
{
initgraph(1080, 880);
settextstyle(25, 20, _T("Courier"));
ExMessage m;
releasecapture();
int flag = 1;
while (flag)
{
rectangle(100, 100, 980, 780);
rectangle(95, 95, 975, 775);
rectangle(300, 330, 500, 370);
rectangle(300, 380, 500, 420);
rectangle(300, 430, 600, 470);
rectangle(300, 480, 500, 520);
outtextxy(340, 300, _T("请选择您的操作: "));
outtextxy(335, 350, _T("1.选择专业统计"));
outtextxy(335, 400, _T("2.选择班级统计"));
outtextxy(335, 450, _T("3.设置指定范围成绩学生统计"));
outtextxy(335, 500, _T("4.退出"));
m = getmessage(EX_MOUSE);
//peekmessage(&m, EX_MOUSE, true);
switch (m.message)
{
case WM_MOUSEMOVE:
continue;
case WM_LBUTTONDOWN:
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 330 && m.y <= 370) {
flag = 0;
closegraph();
return 1;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 380 && m.y <= 420) {
flag = 0;
closegraph();
return 2;
}
if (m.lbutton && m.x >= 300 && m.x <= 600 && m.y >= 430 && m.y <= 470) {
flag = 0;
closegraph();
return 3;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 480 && m.y <= 520) {
flag = 0;
closegraph();
return 4;
}
break;
default:
break;
}
}
closegraph();
return 0;
}
int menu7()//排序控制菜单
{
initgraph(1080, 880);
settextstyle(25, 20, _T("Courier"));
ExMessage m;
releasecapture();
int flag = 1;
while (flag)
{
rectangle(100, 100, 980, 780);
rectangle(95, 95, 975, 775);
rectangle(300, 330, 500, 370);
rectangle(300, 380, 500, 420);
outtextxy(340, 300, _T("请选择您的操作: "));
outtextxy(335, 350, _T("1.降序排序"));
outtextxy(335, 400, _T("2.升序排序"));
m = getmessage(EX_MOUSE);
//peekmessage(&m, EX_MOUSE, true);
switch (m.message)
{
case WM_MOUSEMOVE:
continue;
case WM_LBUTTONDOWN:
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 330 && m.y <= 370) {
flag = 0;
closegraph();
return 1;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 380 && m.y <= 420) {
flag = 0;
closegraph();
return 2;
}
break;
default:
break;
}
}
closegraph();
return 0;
}
int menu8()//查询1
{
initgraph(1080, 880);
settextstyle(25, 20, _T("Courier"));
ExMessage m;
releasecapture();
int flag = 1;
while (flag)
{
rectangle(100, 100, 980, 780);
rectangle(95, 95, 975, 775);
rectangle(300, 330, 500, 370);
rectangle(300, 380, 500, 420);
rectangle(300, 430, 600, 470);
outtextxy(340, 300, _T("***************** "));
outtextxy(335, 350, _T("1.单字段查询"));
outtextxy(335, 400, _T("2.多字段查询"));
outtextxy(335, 450, _T("3.退出"));
outtextxy(335, 500, _T("*****************"));
m = getmessage(EX_MOUSE);
//peekmessage(&m, EX_MOUSE, true);
switch (m.message)
{
case WM_MOUSEMOVE:
continue;
case WM_LBUTTONDOWN:
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 330 && m.y <= 370) {
flag = 0;
closegraph();
return 1;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 380 && m.y <= 420) {
flag = 0;
closegraph();
return 2;
}
if (m.lbutton && m.x >= 300 && m.x <= 600 && m.y >= 430 && m.y <= 470) {
flag = 0;
closegraph();
return 3;
}
break;
default:
break;
}
}
closegraph();
return 0;
}
int menu9()//单字段查询菜单
{
initgraph(1080, 880);
settextstyle(25, 20, _T("Courier"));
ExMessage m;
releasecapture();
int flag = 1;
while (flag)
{
rectangle(100, 100, 980, 780);
rectangle(95, 95, 975, 775);
rectangle(300, 330, 500, 370);
rectangle(300, 380, 500, 420);
rectangle(300, 430, 500, 470);
rectangle(300, 480, 500, 520);
outtextxy(340, 300, _T("请选择您的操作: "));
outtextxy(335, 350, _T("1.按专业查询"));
outtextxy(335, 400, _T("2.按班级查询"));
outtextxy(335, 450, _T("3.按姓名查询"));
outtextxy(335, 500, _T("4.退出"));
m = getmessage(EX_MOUSE);
//peekmessage(&m, EX_MOUSE, true);
switch (m.message)
{
case WM_MOUSEMOVE:
continue;
case WM_LBUTTONDOWN:
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 330 && m.y <= 370) {
flag = 0;
closegraph();
return 1;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 380 && m.y <= 420) {
flag = 0;
closegraph();
return 2;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 430 && m.y <= 470) {
flag = 0;
closegraph();
return 3;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 480 && m.y <= 520) {
flag = 0;
closegraph();
return 4;
}
break;
default:
break;
}
}
closegraph();
return 0;
}
int menu10()//多字段查询菜单
{
initgraph(1080, 880);
settextstyle(25, 20, _T("Courier"));
ExMessage m;
releasecapture();
int flag = 1;
while (flag)
{
rectangle(100, 100, 980, 780);
rectangle(95, 95, 975, 775);
rectangle(300, 330, 500, 370);
rectangle(300, 380, 500, 420);
rectangle(300, 430, 500, 470);
rectangle(300, 480, 500, 520);
outtextxy(340, 300, _T("请选择您的操作: "));
outtextxy(335, 350, _T("1.专业+班级查询"));
outtextxy(335, 400, _T("2.专业+姓名查询"));
outtextxy(335, 450, _T("3.班级+姓名查询"));
outtextxy(335, 500, _T("4.退出"));
m = getmessage(EX_MOUSE);
//peekmessage(&m, EX_MOUSE, true);
switch (m.message)
{
case WM_MOUSEMOVE:
continue;
case WM_LBUTTONDOWN:
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 330 && m.y <= 370) {
flag = 0;
closegraph();
return 1;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 380 && m.y <= 420) {
flag = 0;
closegraph();
return 2;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 430 && m.y <= 470) {
flag = 0;
closegraph();
return 3;
}
if (m.lbutton && m.x >= 300 && m.x <= 500 && m.y >= 480 && m.y <= 520) {
flag = 0;
closegraph();
return 4;
}
break;
default:
break;
}
}
closegraph();
return 0;
}
void start()//开始界面菜单
{
ExMessage emg;
//emg.message = EX_MOUSE;
emg.lbutton = 0;
//emg.mbutton = 0;
//emg.rbutton = 0;
srand((unsigned)time(NULL)); // 随机种子
initgraph(1080, 880); // 创建绘图窗口
settextstyle(25, 20, _T("Courier")); //字体
settextcolor(WHITE);
// 初始化所有星星
for (int i = 0; i < MAXSTAR; i++)
{
InitStar(i);
star[i].x = rand() % 1080;
}
// 绘制星空,按任意键退出
while (!peekmessage(&emg, EX_KEY, true))
{
for (int i = 0; i < MAXSTAR; i++)
{
settextstyle(25, 20, _T("Courier")); //字体
outtextxy(330, 300, _T("欢迎使用英语成绩管理系统!"));
settextstyle(10, 6, _T("Courier")); //字体
outtextxy(400, 350, _T(".......按任意键继续......."));
MoveStar(i);
}
Sleep(20);
}
cleardevice();
closegraph();// 关闭绘图窗口
int l = 0;
//l = menu1();
//printf("%d", l);
//l = menu2();
//printf("%d", l);
//l = menu3();
//printf("%d", l);
//l = menu4(1);
//l = menu4(2);
//l = menu5();
//l = menu6();
//l = menu7();
//l = menu8();
//l = menu9();
//l = menu10();
}
void end()//开始界面菜单
{
ExMessage emg;
//emg.message = EX_MOUSE;
emg.lbutton = 0;
//emg.mbutton = 0;
//emg.rbutton = 0;
srand((unsigned)time(NULL)); // 随机种子
initgraph(1080, 880); // 创建绘图窗口
settextstyle(25, 20, _T("Courier")); //字体
settextcolor(WHITE);
// 初始化所有星星
for (int i = 0; i < MAXSTAR; i++)
{
InitStar(i);
star[i].x = rand() % 1080;
}
// 绘制星空,按任意键退出
while (!peekmessage(&emg, EX_KEY, true))
{
for (int i = 0; i < MAXSTAR; i++)
{
settextstyle(25, 20, _T("Courier")); //字体
outtextxy(330, 300, _T(" 感谢使用! "));
settextstyle(10, 6, _T("Courier")); //字体
outtextxy(400, 350, _T(".......按任意键结束......."));
MoveStar(i);
}
Sleep(20);
}
cleardevice();
closegraph();
}
//int main()
//{
// start();
// end();
// return 0;
//}
question.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <graphics.h>
#include <iostream>
#define QLEN sizeof(struct question)
static int shuq = 0;
struct question
{
char content[100]; //题目内容
double score; //题目分值
char result[20]; //题目答案
struct question* next; //指向下一个题目的指针
};
struct question* create_que(int n, struct question* h)//创建题目信息链表
{
struct question* head = NULL, * p1 = NULL, * p2 = NULL, * p3 = NULL;
int i, f = 0, j;
p3 = h;
for (i = 1; i <= n; i++)
{
p1 = (struct question*)malloc(QLEN);
printf("请输入题目(%d)内容:", i);
getchar();
scanf("%[^\n]", p1->content);
printf("请输入题目(%d)答案:", i);
scanf("%s", &p1->result);
printf("请输入题目(%d)分值:", i);
scanf("%lf", &p1->score);
p1->next = NULL;
if (i == 1) head = p1;
else p2->next = p1;
p2 = p1;
}
return(head);
};
void print_que_t(struct question* head)//打印题目信息的函数
{
struct question* p1_h = NULL;
int i = 0;
p1_h = head;
while (p1_h != NULL)
{
TCHAR s[10], c[100], r[20];
_stprintf(s, _T("%lf"), p1_h->score);
_stprintf(c, _T("%s"), p1_h->content);
_stprintf(r, _T("%s"), p1_h->result);
outtextxy(100, 100, _T("__________________________"));
outtextxy(100, 100 + i * 35, _T("|题目:"));
outtextxy(200, 100 + i * 35, c);
outtextxy(100, 100 + (i + 1) * 35, _T("|题目分数:"));
outtextxy(200, 100 + (i + 1) * 35, s);
outtextxy(100, 100 + (i + 2) * 35, _T("|题目答案:"));
outtextxy(200, 100 + (i + 2) * 35, r);
outtextxy(100, 100 + (i + 3) * 35, _T("__________________________"));
//printf("__________________________\n");
//printf("|题目:%s \n",p1_h->content);
//printf("|题目分数:%lf \n",p1_h->score);
//printf("|题目答案:%s \n",p1_h->result);
p1_h = p1_h->next;
i++;
if (100 + (i + 3) * 35 >= 800)
{
cleardevice();
}
Sleep(20);
}
//printf("__________________________\n");
p1_h = NULL;
}
struct question* print_que_s(struct question* head)//打印题目信息的函数
{
struct question* p1_h = NULL;
p1_h = head;
printf("__________________________\n");
printf("|题目(%.2lf 分):%s \n", p1_h->score, p1_h->content);
printf("__________________________\n");
p1_h = p1_h->next;
return p1_h;
}
struct question* connect_que(struct question* p1_c1, struct question* p2_c1)//题目信息链表链接函数
{
struct question* p3_c1 = NULL;
p3_c1 = p1_c1;
while (1)
{
if (p1_c1->next == NULL) {
break;
}
p1_c1 = p1_c1->next;
}
p1_c1->next = p2_c1;
return (p3_c1);
}
//以上为输入模块函数,下面为功能函数
struct question* load_que(struct question* head)//题目信息文件加载函数
{
FILE* fp_l;
char temp[20];
if ((fp_l = fopen("timu.txt", "r+")) == NULL) {
printf("加载题目信息文档出错。\n");
exit(1);
}
else {
printf("加载题目信息文档成功。\n\n\n");
fgets(temp, 1024, fp_l);
}
int flag = 1;
char content_t[100]; //题目内容
double score_t; //题目分数
char result_t[20]; //题目答案
struct question* p1_lo = NULL, * p2_lo = NULL, * p3_lo = NULL;
p2_lo = (struct question*)malloc(QLEN);
p2_lo->next = NULL;
while (fscanf(fp_l, "%99[^\t]\t%s\t%lf\n", content_t, result_t, &score_t) == 3)
{
if (flag) {
strcpy(p2_lo->content, content_t);
strcpy(p2_lo->result, result_t);
p2_lo->score = score_t;
flag = 0;
p1_lo = p2_lo;
p3_lo = p2_lo;
}
else {
p2_lo = (struct question*)malloc(QLEN);
p2_lo->next = NULL;
strcpy(p2_lo->content, content_t);
strcpy(p2_lo->result, result_t);
p2_lo->score = score_t;
p3_lo->next = p2_lo;
p3_lo = p3_lo->next;
}
shuq++;
}
fclose(fp_l);
return p1_lo;
};
struct question* write_que(struct question* head_wr)//题目信息写入函数
{
FILE* fp_wr;
struct question* p1_wr = NULL;
if ((fp_wr = fopen("timu.txt", "w")) == NULL) {
printf("加载文档出错。\n");
exit(1);
}
fprintf(fp_wr, "%s\t%s\t%s\n", "题目", "答案", "分值");
while (head_wr != NULL) {
fprintf(fp_wr, "%s\t", head_wr->content);
fprintf(fp_wr, "%s\t", head_wr->result);
fprintf(fp_wr, "%.2lf\n", head_wr->score);
head_wr = head_wr->next;
}
fclose(fp_wr);
printf("数据写入成功!\n\n\n");
return p1_wr;
}
student.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stdbool.h>
#include <m.h>
#include <graphics.h>
#define SLEN sizeof(struct student)
static int shus = 0;
struct student
{
char pwd[20]; //学生密码
char subject[20]; //学生专业
char stuclass[10]; //学生班级
char name[20]; //学生姓名
double scores; //学生总分
char result[20]; //学生答案
struct student* next; //指向下一个学生的指针
};
void generateAnswerFile(struct student* head)
{
struct student* p = NULL;
p = head;
char filename[20]; // 文件名
sprintf(filename, "Answers/%s%s-%s.txt", p->subject, p->stuclass, p->name);
FILE* file = fopen(filename, "r");
if (file == NULL) {
// 文件不存在,创建文件
file = fopen(filename, "w");
if (file == NULL) {
fprintf(stderr, "无法创建文件 %s\n", filename);
exit(1); // 处理文件创建失败的情况
}
// 可以在这里写入初始内容,或者后续根据需要进行写入
// fprintf(file, "初始内容\n");
fprintf(file, "%s", p->result);
fclose(file);
}
else {
fclose(file);
// 文件已存在,可能进行其他操作
}
}
void print_stu(struct student* head)//打印学生信息的函数
{
struct student* p1_h = NULL;
p1_h = head;
printf("%s\t%s\t%s\t%s\t%.2lf\n", p1_h->subject, p1_h->stuclass, p1_h->name, p1_h->result, p1_h->scores);
printf("__________________________________\n");
}
struct student* connect_stu(struct student* p1_c1, struct student* p2_c1)//学生信息链表链接函数
{
struct student* p3_c1 = NULL;
p3_c1 = p1_c1;
while (1)
{
if (p1_c1->next == NULL) {
break;
}
p1_c1 = p1_c1->next;
}
p1_c1->next = p2_c1;
return (p3_c1);
}
//以上为输入模块函数,下面为功能函数
struct student* register_stu(struct student* h, struct student* r)//注册学生信息
{
struct student* head = NULL, * p1 = NULL, * p3 = NULL, * loggedStu = NULL;
p3 = h;
p1 = (struct student*)malloc(SLEN);
char n[20], s[20], c[20], p[20], temp[20];
printf("请输入您的姓名:");
scanf("%s", n);
printf("请输入您的专业:");
scanf("%s", s);
printf("请输入您的班级:");
scanf("%s", c);
while (p3) {
if (strcmp(n, p3->name) == 0 && strcmp(c, p3->stuclass) == 0 && strcmp(s, p3->subject) == 0) {
printf("该学生账号已被注册!\n");
printf("请输入您的密码:");
scanf("%s", p);
if (strcmp(p, p3->pwd) == 0)
{
loggedStu = p3;
break;
}
int i = 0;
do {
printf("密码错误!请输入登录密码(您还有%d次机会尝试):", 5 - i);
scanf("%s", p);
} while (strcmp(p, p3->pwd) != 0 && ++i < 5);
if (strcmp(p, p3->pwd) != 0) {
printf("密码错误!");
exit(1);
}
else {
system("cls");
loggedStu = p3;
break;
}
}
else {
p3 = p3->next;
}
}
if (p3 == NULL) {
printf("请输入您的密码:");
scanf("%s", p);
printf("请再次输入您的密码:");
scanf("%s", temp);
while (strcmp(p, temp) != 0) {
printf("两次密码输入不一致,请重新尝试!\n");
printf("请输入您的密码:");
scanf("%s", p);
printf("请再次输入您的密码:");
scanf("%s", temp);
}
strcpy(p1->name, n);
strcpy(p1->pwd, p);
strcpy(p1->stuclass, c);
strcpy(p1->subject, s);
p1->scores = 0;
strcpy(p1->result, "未答");
generateAnswerFile(p1);
p1->next = NULL;
printf("注册成功!已为您自动登录,请校验您的身份信息:\n");
printf("__________________________________\n");
printf("专业\t班级\t姓名\t状态\t总分\n");
printf("__________________________________\n");
print_stu(p1);
printf("\n按任意键继续......\n");
system("pause");
system("cls");
r = p1;
loggedStu = p1;
}
if (h != NULL) {
h = connect_stu(h, r);
}
else {
h = r;
}
return(loggedStu);
}
struct student* login_stu(struct student* h)//学生登录
{
struct student* head = NULL, * p1 = NULL, * p3 = NULL, * loggedStu = NULL;
int f = 0;
p3 = h;
p1 = (struct student*)malloc(SLEN);
char n[20], s[20], c[20], p[20];
printf("请输入您的姓名:");
scanf("%s", n);
printf("请输入您的密码:");
scanf("%s", p);
while (p3) {
if (strcmp(n, p3->name) == 0 && strcmp(p, p3->pwd) == 0) {
printf("登录中……\n");
generateAnswerFile(p3);
printf("请校验您的身份信息:\n");
print_stu(p3);
printf("\n按任意键继续......\n");
system("pause");
system("cls");
loggedStu = p3;
break;
}
else if (strcmp(n, p3->name) == 0 && strcmp(p, p3->pwd) != 0) {
int i = 0;
do {
printf("密码错误!请输入登录密码(您还有%d次机会尝试):", 5 - i);
scanf("%s", p);
} while (strcmp(p, p3->pwd) != 0 && ++i < 5);
if (strcmp(p, p3->pwd) != 0) {
printf("密码错误!");
exit(1);
}
else {
printf("登录中……\n");
generateAnswerFile(p3);
printf("请校验您的身份信息:\n");
print_stu(p3);
printf("\n按任意键继续......\n");
loggedStu = p3;
system("cls");
break;
}
}
else {
p3 = p3->next;
}
}
if (p3 == NULL) {
printf("未查询到您的账户,请先注册!\n");
printf("\n按任意键继续......\n");
system("pause");
system("cls");
return NULL;
}
return(loggedStu);
}
struct student* reback(struct student* h, struct student* r) { //找回密码
struct student* head = NULL, * p1 = NULL, * p3 = NULL, * loggedStu = NULL;
int f = 0;
p3 = h;
p1 = (struct student*)malloc(SLEN);
char n[20], s[20], c[20], p[20];
printf("请输入您的姓名:");
scanf("%s", n);
printf("请输入您的密码:");
scanf("%s", p);
while (p3) {
if (strcmp(n, p3->name) == 0 && strcmp(p, p3->pwd) == 0) {
printf("登录中……\n");
generateAnswerFile(p3);
printf("请校验您的身份信息:\n");
print_stu(p3);
printf("\n按任意键继续......\n");
system("pause");
system("cls");
loggedStu = p3;
break;
}
else if (strcmp(n, p3->name) == 0 && strcmp(p, p3->pwd) != 0) {
int i = 0;
do {
printf("密码错误!请输入登录密码(您还有%d次机会尝试):", 5 - i);
scanf("%s", p);
} while (strcmp(p, p3->pwd) != 0 && ++i < 5);
if (strcmp(p, p3->pwd) != 0) {
printf("密码错误!");
exit(1);
}
else {
loggedStu = p3;
system("cls");
break;
}
}
else {
p3 = p3->next;
}
}
if (p3 == NULL) {
printf("未查询到您的账户,请先注册!\n");
printf("\n按任意键继续......\n");
system("pause");
system("cls");
return NULL;
}
return(loggedStu);
}
struct student* find(struct student* p1_pf)//学生信息查找函数
{
struct student* p2_pf = NULL;
int i = 0, n, f = 0, l = 1;
char a[20];
while (l)
{
p2_pf = p1_pf;
f = menu8();
//printf("_____________________________________\n");
//printf("|1.单字段查询 | 2.多字段查询 |\n");
//printf("|3.退出 | |\n");
//printf("_____________________________________\n");
//printf("请输入对应数字键来使用对应功能:");
//scanf("%d",&f);
//printf("\n....................................................\n\n");
if (f == 1) {
n = menu9();
//printf("_____________________________________\n");
//printf("|1.按专业查询 | 2.按班级查询 |\n");
//printf("|3.按姓名查询 | 4.退出 |\n");
//printf("_____________________________________\n");
//printf("请输入对应数字键来使用对应功能:");
//scanf("%d",&n);
if (n == 1) {
printf("请输入查询专业:");
char temp[20];
scanf("%s", temp);
printf("__________________________________\n");
printf("专业\t班级\t姓名\t状态\t总分\n");
printf("__________________________________\n");
while (p2_pf) {
if (strcmp(p2_pf->subject, temp) == 0) {
print_stu(p2_pf);
}
p2_pf = p2_pf->next;
}
}
else if (n == 2) {
printf("请输入查询班级:");
char temp[20];
scanf("%s", temp);
printf("__________________________________\n");
printf("专业\t班级\t姓名\t状态\t总分\n");
printf("__________________________________\n");
while (p2_pf) {
if (strcmp(p2_pf->stuclass, temp) == 0) {
print_stu(p2_pf);
}
p2_pf = p2_pf->next;
}
}
else if (n == 3) {
printf("请输入查询姓名:");
char temp[20];
scanf("%s", temp);
printf("__________________________________\n");
printf("专业\t班级\t姓名\t状态\t总分\n");
printf("__________________________________\n");
while (p2_pf) {
if (strcmp(p2_pf->name, temp) == 0) {
print_stu(p2_pf);
}
p2_pf = p2_pf->next;
}
}
else if (n == 4) {
printf("退出\n");
break;
}
}
else if (f == 2) {
n = menu10();
//printf("_____________________________________\n");
//printf("|1.专业+班级查询 | 2.专业+姓名查询 |\n");
//printf("|3.班级+姓名查询 | 4.退出 |\n");
//printf("_____________________________________\n");
//printf("请输入对应数字键来使用对应功能:");
//scanf("%d",&n);
if (n == 1) {
printf("请输入查询专业:");
char temp1[20], temp2[20];
scanf("%s", temp1);
printf("请输入查询班级:");
scanf("%s", temp2);
printf("__________________________________\n");
printf("专业\t班级\t姓名\t状态\t总分\n");
printf("__________________________________\n");
while (p2_pf) {
if (strcmp(p2_pf->subject, temp1) == 0 && strcmp(p2_pf->stuclass, temp2) == 0) {
print_stu(p2_pf);
}
p2_pf = p2_pf->next;
}
}
else if (n == 2) {
printf("请输入查询专业:");
char temp1[20], temp2[20];
scanf("%s", temp1);
printf("请输入查询姓名:");
scanf("%s", temp2);
printf("__________________________________\n");
printf("专业\t班级\t姓名\t状态\t总分\n");
printf("__________________________________\n");
while (p2_pf) {
if (strcmp(p2_pf->subject, temp1) == 0 && strcmp(p2_pf->stuclass, temp2) == 0) {
print_stu(p2_pf);
}
p2_pf = p2_pf->next;
}
}
else if (n == 3) {
printf("请输入查询班级:");
char temp1[20], temp2[20];
scanf("%s", temp1);
printf("请输入查询姓名:");
scanf("%s", temp2);
printf("__________________________________\n");
printf("专业\t班级\t姓名\t状态\t总分\n");
printf("__________________________________\n");
while (p2_pf) {
if (strcmp(p2_pf->stuclass, temp1) == 0 && strcmp(p2_pf->name, temp2) == 0) {
print_stu(p2_pf);
}
p2_pf = p2_pf->next;
}
}
else if (n == 4) {
printf("退出\n");
break;
}
}
else if (f == 3) {
printf("退出\n");
break;
}
else {
printf("未知操作,请重新输入!\n");
}
}
return p2_pf;
}
struct student* delete_stu(struct student* head) {//学生信息删除函数
char delete_name[20];
int found = 0;
printf("请输入要删除的学生姓名:");
scanf("%s", delete_name);
struct student* current = head;
struct student* prev = NULL;
FILE* fp_stu1 = fopen("stu1.txt", "a"); // 以追加模式打开文件
while (current != NULL) {
if (strcmp(current->name, delete_name) == 0) {
found = 1;
// 将被删除的学生信息写入 stu1.txt
fprintf(fp_stu1, "%s\n", current->name);
fprintf(fp_stu1, "%s\t", current->subject);
fprintf(fp_stu1, "%s\t", current->stuclass);
fprintf(fp_stu1, "%s\t", current->name);
fprintf(fp_stu1, "%s\t", current->pwd);
fprintf(fp_stu1, "%s\t", current->result);
fprintf(fp_stu1, "%.2lf\n", current->scores);
// 保存前一个节点的指针
if (prev != NULL) {
prev->next = current->next;
}
else {
// 如果删除的是链表的头节点
head = current->next;
}
// 释放被删除节点的内存
free(current);
current = NULL;
printf("学生 %s 的信息已删除并存储到 stu1.txt。\n", delete_name);
break;
}
else {
prev = current;
current = current->next;
}
}
if (!found) {
printf("未找到要删除的学生。\n");
}
fclose(fp_stu1);
return head;
}
struct student* load_stu(struct student* head)//学生信息文件加载函数
{
FILE* fp_l;
char temp[1024];
if ((fp_l = fopen("stu.txt", "r+")) == NULL) {
printf("加载学生信息文档出错。\n");
exit(1);
}
else {
printf("加载学生信息文档成功。\n\n\n");
fgets(temp, 1024, fp_l);
}
int flag = 1;
char name_t[20]; //学生姓名
char subject_t[20];
char stuclass_t[20];
char result_t[20];
char pwd_t[20];
double scores_t; //学生分数
struct student* p1_lo = NULL, * p2_lo = NULL, * p3_lo = NULL;
p2_lo = (struct student*)malloc(SLEN);
p2_lo->next = NULL;
while (fscanf(fp_l, "%s\t%s\t%s\t%s\t%s\t%lf\n", subject_t, stuclass_t, name_t, pwd_t, result_t, &scores_t) == 6)//检测文件是否结束
{
if (flag) {
strcpy(p2_lo->name, name_t);
strcpy(p2_lo->subject, subject_t);
strcpy(p2_lo->stuclass, stuclass_t);
strcpy(p2_lo->result, result_t);
strcpy(p2_lo->pwd, pwd_t);
p2_lo->scores = scores_t;
flag = 0;
p1_lo = p2_lo;
p3_lo = p2_lo;
}
else {
p2_lo = (struct student*)malloc(SLEN);
p2_lo->next = NULL;
strcpy(p2_lo->name, name_t);
strcpy(p2_lo->subject, subject_t);
strcpy(p2_lo->stuclass, stuclass_t);
strcpy(p2_lo->result, result_t);
strcpy(p2_lo->pwd, pwd_t);
p2_lo->scores = scores_t;
p3_lo->next = p2_lo;
p3_lo = p3_lo->next;
}
shus++;
}
fclose(fp_l);
return p1_lo;
};
struct student* write_stu(struct student* head_wr)//学生信息写入函数
{
FILE* fp_wr;
struct student* p1_wr = NULL;
if ((fp_wr = fopen("stu.txt", "w")) == NULL) {
printf("加载文档出错。\n");
exit(1);
}
fprintf(fp_wr, "%s\t%s\t%s\t%s\t%s\t%s\n", "专业", "班级", "姓名", "密码", "状态", "总分");
while (head_wr != NULL) {
fprintf(fp_wr, "%s\t", head_wr->subject);
fprintf(fp_wr, "%s\t", head_wr->stuclass);
fprintf(fp_wr, "%s\t", head_wr->name);
fprintf(fp_wr, "%s\t", head_wr->pwd);
fprintf(fp_wr, "%s\t", head_wr->result);
fprintf(fp_wr, "%.2lf\n", head_wr->scores);
head_wr = head_wr->next;
}
fclose(fp_wr);
printf("数据写入成功!\n\n\n");
system("cls");
return p1_wr;
}
void swap_stu(struct student* s1, struct student* s2) {
char sub[20], scl[20], res[20], pwd[20];
char n[20];
int p;
strcpy(n, s1->name);
p = s1->scores;
strcpy(sub, s1->subject);
strcpy(scl, s1->stuclass);
strcpy(res, s1->result);
strcpy(pwd, s1->pwd);
strcpy(s1->name, s2->name);
strcpy(s1->subject, s2->subject);
strcpy(s1->stuclass, s2->stuclass);
strcpy(s1->result, s2->result);
strcpy(s1->pwd, s2->pwd);
s1->scores = s2->scores;
s2->scores = p;
strcpy(s2->name, n);
strcpy(s2->subject, sub);
strcpy(s2->stuclass, scl);
strcpy(s2->result, res);
strcpy(s2->pwd, pwd);
}
struct student* sort_stu(struct student* head)//学生信息排序函数(使用冒泡排序法)
{
struct student* p1_sot = NULL, * p2_sot = NULL, * p3_sot = NULL;
int t, i, j, fl = 0;
bool isDown = false;
i = menu7();
//printf("_____________________________________\n");
//printf("|1.降序排序 | 2.升序排序 |\n");
//printf("_____________________________________\n");
//printf("请输入对应数字键来使用对应功能:");
//scanf("%d",&i);
if (i == 1) isDown = true;
else isDown = false;
for (t = 0; t < shus - 1; t++) {
p1_sot = head;
p3_sot = p1_sot->next;
for (j = 0; j < shus - 1; j++) {
if (isDown) {
if (p3_sot->scores > p1_sot->scores) {
swap_stu(p3_sot, p1_sot);
fl = 1;
}
p3_sot = p3_sot->next;
p1_sot = p1_sot->next;
}
else {
if (p3_sot->scores < p1_sot->scores) {
swap_stu(p3_sot, p1_sot);
fl = 1;
}
p3_sot = p3_sot->next;
p1_sot = p1_sot->next;
}
}
}
if (fl) {
printf("排序成功!\n");
}
return p2_sot;
}
struct student* count(struct student* head)//班级学生数量与总分、平均分统计函数
{
struct student* p1_cal = NULL, * p2_cal = NULL;
int num = 0, i, j;
double sum = 0, avg = 0;
p1_cal = head;
i = menu5();
//printf("_____________________________________\n");
//printf("|1.全统计 | 2.条件统计 |\n");
//printf("|Other Keys.退出 |\n");
//printf("_____________________________________\n");
//printf("请输入对应数字键来使用对应功能:");
//scanf("%d",&i);
if (i == 1) {
while (p1_cal != NULL)//逐个遍历
{
num += 1;
sum += (p1_cal->scores);
p1_cal = p1_cal->next;
}
avg = sum / num;
printf("_________________________\n");
printf("|学生数量:%d \n", num);
printf("|班级总分:%lf \n", sum);
printf("|班级平均分:%lf \n", avg);
printf("_________________________\n\n");
return p2_cal;
}
else if (i == 2) {
j = menu6();
//printf("_____________________________________\n");
//printf("|1.选择专业统计 |2.选择班级统计 |\n");
//printf("|3.设置指定范围成绩学生统计 |\n");
//printf("|Other Keys.退出 |\n");
//printf("_____________________________________\n");
//printf("请输入对应数字键来使用对应功能:");
//scanf("%d",&j);
if (j == 1) {
char subject[20];
reset1:
p1_cal = head;
printf("请输入查询专业:");
scanf("%s", subject);
while (p1_cal != NULL) {
if (strcmp(p1_cal->subject, subject) == 0)
break;
p1_cal = p1_cal->next;
}
if (p1_cal == NULL) {
printf("所输专业不存在!请重新输入!\n");
goto reset1;
}
p1_cal = head;
while (p1_cal != NULL)//逐个遍历
{
if (strcmp(p1_cal->subject, subject) == 0) {
num += 1;
sum += (p1_cal->scores);
}
p1_cal = p1_cal->next;
}
avg = sum / num;
printf("%s专业学生统计如下:\n", subject);
printf("_________________________\n");
printf("|学生数量:%d \n", num);
printf("|班级总分:%lf \n", sum);
printf("|班级平均分:%lf \n", avg);
printf("_________________________\n\n");
}
else if (j == 2) {
char stuclass[20];
reset2:
p1_cal = head;
printf("请输入查询班级:");
scanf("%s", stuclass);
while (p1_cal != NULL) {
if (strcmp(p1_cal->stuclass, stuclass) == 0)
break;
p1_cal = p1_cal->next;
}
if (p1_cal == NULL) {
printf("所输班级不存在!请重新输入!\n");
goto reset2;
}
p1_cal = head;
while (p1_cal != NULL)//逐个遍历
{
if (strcmp(p1_cal->stuclass, stuclass) == 0) {
num += 1;
sum += (p1_cal->scores);
}
p1_cal = p1_cal->next;
}
avg = sum / num;
printf("%s班学生统计如下:\n", stuclass);
printf("_________________________\n");
printf("|学生数量:%d \n", num);
printf("|班级总分:%lf \n", sum);
printf("|班级平均分:%lf \n", avg);
printf("_________________________\n\n");
}
else if (j == 3) {
int min, max;
reset3:
printf("请输入成绩范围最小值:");
scanf("%d", &min);
printf("请输入成绩范围最大值:");
scanf("%d", &max);
if (min > max) {
printf("最小值大于最大值,筛选无效!请重新输入!\n");
goto reset3;
}
while (p1_cal != NULL)//逐个遍历
{
if (p1_cal->scores >= min && p1_cal->scores <= max) {
num += 1;
sum += (p1_cal->scores);
}
p1_cal = p1_cal->next;
}
avg = sum / num;
printf("分数在%d分-%d分范围的学生统计如下:\n", min, max);
printf("_________________________\n");
printf("|学生数量:%d \n", num);
printf("|班级总分:%lf \n", sum);
printf("|班级平均分:%lf \n", avg);
printf("_________________________\n\n");
}
else {
return p2_cal;
}
}
else {
return p2_cal;
}
}
teacher.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stdbool.h>
#include <graphics.h>
#define TLEN sizeof(struct teacher)
static int shut = 0;
struct teacher //typedef 可以定义结构体别名
{
char pwd[20]; //密码
char name[15];//姓名为字符串
struct teacher* next;
};
struct teacher* connect_tea(struct teacher* p1_c1, struct teacher* p2_c1)//教师信息链表链接函数
{
struct teacher* p3_c1 = NULL;
p3_c1 = p1_c1;
while (1)
{
if (p1_c1->next == NULL) {
break;
}
p1_c1 = p1_c1->next;
}
p1_c1->next = p2_c1;
return (p3_c1);
}
struct teacher* register_tea(struct teacher* h, struct teacher* r)//注册教师信息
{
struct teacher* head = NULL, * p1 = NULL, * p3 = NULL, * loggedTea = NULL;
p3 = h;
p1 = (struct teacher*)malloc(TLEN);
char n[20], p[20], temp[20];
printf("请输入您的姓名:");
scanf("%s", n);
while (p3) {
if (strcmp(n, p3->name) == 0) {
printf("该教师账号已被注册!\n");
printf("请输入您的密码:");
scanf("%s", p);
if (strcmp(p, p3->pwd) == 0)
{
loggedTea = p3;
break;
}
int i = 0;
do {
printf("密码错误!请输入登录密码(您还有%d次机会尝试):", 5 - i);
scanf("%s", p);
} while (strcmp(p, p3->pwd) != 0 && ++i < 5);
if (strcmp(p, p3->pwd) != 0) {
printf("密码错误!");
exit(1);
}
else {
system("cls");
loggedTea = p3;
break;
}
}
else {
p3 = p3->next;
}
}
if (p3 == NULL) {
printf("请输入您的密码:");
scanf("%s", p);
printf("请再次输入您的密码:");
scanf("%s", temp);
while (strcmp(p, temp) != 0) {
printf("两次密码输入不一致,请重新尝试!\n");
printf("请输入您的密码:");
scanf("%s", p);
printf("请再次输入您的密码:");
scanf("%s", temp);
}
strcpy(p1->name, n);
strcpy(p1->pwd, p);
p1->next = NULL;
printf("注册成功!尊敬的%s,已为您自动登录,\n", p1->name);
printf("\n按任意键继续......\n");
system("pause");
system("cls");
r = p1;
loggedTea = p1;
}
if (h != NULL) {
h = connect_tea(h, r);
}
else {
h = r;
}
return(loggedTea);
}
struct teacher* login_tea(struct teacher* h)//教师登录
{
struct teacher* head = NULL, * p1 = NULL, * p3 = NULL, * loggedTea = NULL;
int f = 0;
p3 = h;
p1 = (struct teacher*)malloc(TLEN);
char n[20], p[20];
printf("请输入您的姓名:");
scanf("%s", n);
printf("请输入您的密码:");
scanf("%s", p);
while (p3) {
if (strcmp(n, p3->name) == 0 && strcmp(p, p3->pwd) == 0) {
printf("欢迎回来,%s老师!\n", p3->name);
printf("\n按任意键继续......\n");
system("pause");
system("cls");
loggedTea = p3;
break;
}
else if (strcmp(n, p3->name) == 0 && strcmp(p, p3->pwd) != 0) {
int i = 0;
do {
printf("密码错误!请输入登录密码(您还有%d次机会尝试):", 5 - i);
scanf("%s", p);
} while (strcmp(p, p3->pwd) != 0 && ++i < 5);
if (strcmp(p, p3->pwd) != 0) {
printf("密码错误!");
exit(1);
}
else {
loggedTea = p3;
system("cls");
break;
}
}
else {
p3 = p3->next;
}
}
if (p3 == NULL) {
printf("未查询到您的账户,请先注册!\n");
printf("\n按任意键继续......\n");
system("pause");
system("cls");
return NULL;
}
return(loggedTea);
}
struct teacher* load_tea(struct teacher* head)//教师信息文件加载函数
{
FILE* fp_l;
char temp[1024];
if ((fp_l = fopen("teachers.txt", "r+")) == NULL) {
printf("加载教师信息文档出错。\n");
exit(1);
}
else {
printf("加载教师信息文档成功。\n\n\n");
fgets(temp, 1024, fp_l);
}
int flag = 1;
char name_t[20]; //教师姓名
char pwd_t[20];
struct teacher* p1_lo = NULL, * p2_lo = NULL, * p3_lo = NULL;
p2_lo = (struct teacher*)malloc(TLEN);
p2_lo->next = NULL;
while (fscanf(fp_l, "%s\t%s\n", name_t, pwd_t) == 2)//检测文件是否结束
{
if (flag) {
strcpy(p2_lo->name, name_t);
strcpy(p2_lo->pwd, pwd_t);
flag = 0;
p1_lo = p2_lo;
p3_lo = p2_lo;
}
else {
p2_lo = (struct teacher*)malloc(TLEN);
p2_lo->next = NULL;
strcpy(p2_lo->name, name_t);
strcpy(p2_lo->pwd, pwd_t);
p3_lo->next = p2_lo;
p3_lo = p3_lo->next;
}
shut++;
}
fclose(fp_l);
return p1_lo;
};
struct teacher* write_tea(struct teacher* head_wr)//学生信息写入函数
{
FILE* fp_wr;
struct teacher* p1_wr = NULL;
if ((fp_wr = fopen("teachers.txt", "w")) == NULL) {
printf("加载文档出错。\n");
exit(1);
}
fprintf(fp_wr, "%s\t%s\n", "姓名", "密码");
while (head_wr != NULL) {
fprintf(fp_wr, "%s\t", head_wr->name);
fprintf(fp_wr, "%s\n", head_wr->pwd);
head_wr = head_wr->next;
}
fclose(fp_wr);
printf("数据写入成功!\n\n\n");
system("cls");
return p1_wr;
}
main.cpp
#define _CRT_SECURE_NO_WARNINGS
#include "student.h"
#include "teacher.h"
#include "question.h"
#include "exam.h"
#include "headfile.h"
#include <m.h>
#include <graphics.h>
int main() {
struct teacher* tlist1 = NULL, * tlist2 = NULL, * tflag = NULL, * loggedTea = NULL;//教师信息
struct student* slist1 = NULL, * slist2 = NULL, * sflag = NULL, * loggedStu = NULL;// 学生信息
struct question* form1 = NULL, * form2 = NULL, * form3 = NULL, * qflag = NULL; //题目信息
int act = 0, j = 0, n = 0, num, k;
bool isTeacher = false, isLogin = false;
detectFileExistence();
tlist1 = load_tea(tlist1);//加载教师信息
slist1 = load_stu(slist1);//加载学生信息
form1 = load_que(form1);//加载题目信息
while (!isLogin) {
start();
k = 0;
act = menu1();
system("cls");//清屏操作,以下同理
//printf("______________________________________________________________________\n");
//printf("....................欢迎使用英语成绩管理系统..........................\n");
//printf("______________________________________________________________________\n");
//printf(". 请选择您的操作: .\n");
//printf(". 1.登录账户 .\n");
//printf(". 2.注册账户 .\n");
//printf(". 3.找回密码 .\n");
//printf(". 4.退出系统 .\n");
//printf("请输入1、2、3、4来进行对应操作。\n请问您要进行的操作是:");
//scanf("%d",&act);
switch (act) {
case 1:
while (k != 3 && !isLogin) {
k = menu4(2);
//printf("______________________________________________________________________\n");
//printf(". 请选择您要登录的账户类型: .\n");
//printf(". 1.教师账户 .\n");
//printf(". 2.学生账户 .\n");
//printf(". 3.返回上级 .\n");
//printf("请输入1、2、3:");
//scanf("%d",&k);
switch (k) {
case 1:
loggedTea = login_tea(tlist1);
if (loggedTea == NULL) exit(1);
isTeacher = true;
break;
case 2:
loggedStu = login_stu(slist1);
isTeacher = false;
break;
case 3:
isTeacher = false;
break;
default:
printf("请输入正确选项!\n");
break;
}
if (loggedTea != NULL || loggedStu != NULL) {
isLogin = true;
}
}
break;
case 2:
while (k != 3 && !isLogin) {
k = menu4(1);
//printf("______________________________________________________________________\n");
//printf(". 请选择您要注册的账户类型: .\n");
//printf(". 1.教师账户 .\n");
//printf(". 2.学生账户 .\n");
//printf(". 3.返回上级 .\n");
//printf("请输入1、2、3:");
//scanf("%d",&k);
switch (k) {
case 1:
loggedTea = register_tea(tlist1, tlist2);
tflag = write_tea(tlist1);
isTeacher = true;
break;
case 2:
loggedStu = register_stu(slist1, slist2);
sflag = write_stu(slist1);
isTeacher = false;
break;
case 3:
isTeacher = false;
break;
default:
printf("请输入正确选项!\n");
break;
}
if (loggedTea != NULL || loggedStu != NULL) {
isLogin = true;
}
}
break;
case 3:
// reback();
break;
case 4:
goto End;
break;
default:
printf("请输入正确的选项!\n");
}
}
while (isLogin == true) {
if (isTeacher) {//如果是老师
n = menu3();
//printf("______________________________________________________________________\n");
//printf("....................欢迎使用英语成绩管理系统..........................\n");
//printf("______________________________________________________________________\n");
//printf(". 您可以继续进行的操作是: .\n");
//printf(". 1.录入题目。 .\n");
//printf(". 2.计算成绩。 .\n");
//printf(". 3.显示成绩。 .\n");
//printf(". 4.查询学生成绩。 .\n");
//printf(". 5.删除学生。 .\n");
//printf(". 6.统计学生成绩。 .\n");
//printf(". 7.排序。 .\n");
//printf(". 8.退出。 .\n");
//printf("请输入对应数字键来进行对应操作。\n请问您要进行的操作是:");
//scanf("%d",&n);
initgraph(1080, 880);
settextstyle(25, 20, _T("Courier"));
if (n == 1) {
reset:
outtextxy(200, 200, _T("请输入您要录入的题目数量: "));
//printf("请输入您要录入的题目数量:");
getchar();
scanf("%d", &num);
TCHAR s[5];
_stprintf(s, _T("%d"), num);
outtextxy(200, 240, s);
if (num <= 0) {
outtextxy(200, 280, _T("非法输入!请输入一个大于零的数字!"));
//printf("非法输入!请输入一个大于零的数字!\n");
goto reset;
}
else {
form2 = create_que(num, form1);
if (form1 != NULL) {//判断是否已经生成链表
form1 = connect_que(form1, form2);//将新链表与旧链表链接
}
else {
form1 = form2;
}
outtextxy(200, 320, _T("这是您输入的题目信息:"));
cleardevice();
//printf("这是您输入的题目信息:\n");
print_que_t(form2);
outtextxy(10, 20, _T("按任意键继续......"));
ExMessage m;
m = getmessage(EX_KEY || EX_MOUSE);
if (m.message == EX_KEY || m.message == EX_MOUSE)
{
closegraph();
}
//printf("\n按任意键继续......\n");
//system("pause");
}
}
else if (n == 2) {
judge(form1, slist1);// 计算成绩
printf("\n按任意键继续......\n");
system("pause");
system("cls");
}
else if (n == 3) {
printf("__________________________________\n");
printf("专业\t班级\t姓名\t状态\t总分\n");
printf("__________________________________\n");
struct student* show = NULL;
show = slist1;
while (show != NULL) {
generateAnswerFile(show);
print_stu(show);// 显示成绩
show = show->next;
}
printf("\n按任意键继续......\n");
system("pause");
system("cls");
}
else if (n == 4) {
sflag = find(slist1);//查询学生成绩
printf("\n按任意键继续......\n");
system("pause");
system("cls");
}
else if (n == 5) {
struct student* show = NULL;
show = slist1;
printf("__________________________________\n");
printf("专业\t班级\t姓名\t状态\t总分\n");
printf("__________________________________\n");
while (show != NULL) {
print_stu(show);// 显示成绩
show = show->next;
}
slist1 = delete_stu(slist1);//删除学生
printf("\n按任意键继续......\n");
system("pause");
system("cls");
}
else if (n == 6) {
count(slist1);//统计学生成绩
printf("\n按任意键继续......\n");
system("pause");
system("cls");
}
else if (n == 7) {
sort_stu(slist1);//排序
printf("__________________________________\n");
printf("专业\t班级\t姓名\t状态\t总分\n");
printf("__________________________________\n");
struct student* show = NULL;
show = slist1;
while (show != NULL) {
print_stu(show);// 显示成绩
show = show->next;
}
printf("\n按任意键继续......\n");
system("pause");
system("cls");
}
else if (n == 8) {
isLogin = false;
system("cls");
}
}
else if (!isTeacher) {//如果是学生
n = menu2();
//printf("______________________________________________________________________\n");
//printf("....................欢迎使用英语考试系统..........................\n");
//printf("______________________________________________________________________\n");
//printf(". 您可以继续进行的操作是: .\n");
//printf(". 1.开始答题。 .\n");
//printf(". 2.查看个人信息。 .\n");
//printf(". 3.退出。 .\n");
//printf("请输入对应数字键来进行对应操作。\n请问您要进行的操作是:");
//scanf("%d",&n);
if (n == 1) {
confirm:
getchar();
printf("确定要开始答题吗?这将会清除掉你原有的答案!(Y/N)");
char confirm = getchar();
if (confirm == 'N' || confirm == 'n') {
system("cls");
}
else if (confirm == 'Y' || confirm == 'y') {
strcpy(loggedStu->result, "\0");
system("cls");
form2 = form1;
while (form2 != NULL)
{
char answer[20];
form2 = print_que_s(form2);//读取题目并返回下一个链表直到NULL
getchar();
scanf("%[^\n]", answer);
record(loggedStu, answer);
}
strcpy(loggedStu->result, "已答");
printf("答题完成!");
printf("\n按任意键继续......\n");
system("pause");
system("cls");
}
else {
printf("请输入Y或者N!");
goto confirm;
}
}
else if (n == 2) {
printf("__________________________________\n");
printf("专业\t班级\t姓名\t状态\t总分\n");
printf("__________________________________\n");
print_stu(loggedStu);
printf("\n按任意键继续......\n");
system("pause");
system("cls");
}
else if (n == 3) {
isLogin = false;
system("cls");
}
}
}
End:
tflag = write_tea(tlist1);
sflag = write_stu(slist1);
qflag = write_que(form1);
system("cls");
end();
//printf(".......................程序结束..........................\n");
//printf(".......................感谢使用..........................\n");
//system("pause");
return 0;
}