本文首发于2021年7月18日19:21:06。

注意:直接复制代码会无法运行,因为没有资源文件(图片、文本文件),从下面的github链接或交流群中下载代码或注释指定代码,有关此问题,例如:无法运行等,一律不予回复。望周知。(20220611注)


我的小站——半生瓜のblog

代码文件下载链接——链接


学生成绩管理系统

  • 学生成绩管理系统
    • 效果图
    • 结构图
    • 流程图
    • 流程&注意要点
    • 代码实现

学生成绩管理系统

效果图

结构图

流程图

流程&注意要点

  • 核心部分——EasyX显示图形界面,结构体数组和文件操作负责对数据进行各种操作。
  • 只要一进去程序就对存储数据的文件进行读取,如果有数据直接读到学生结构体数组里面,得到当前结构体数组中的数据数量(几个人),并将所有数据打印到屏幕上。
  • 管理员用户
    • 输入密码验证——读取文件——验证用户输入是否正确。
    • 显示所有数据——如果通过文件读到了数据会被打印到屏幕上,反之。如果没有读到数据,在添加数据之前都会在屏幕上显示"当前记录为空!"。
      • 各种方式的排序——对当前结构体数组中成员的数据,依照"按xx排序",重新排序,均采用冒泡排序。其中值得注意的是,貌似EasyX的InputBox只能将你输入的内容保存到字符数组中,所以你需要将录入的成绩数据通过atof函数转化为浮点型,这里我采用的方法是: 先按照结构体数组中数据的存储顺序将每个人的某科成绩转化浮点型存储到一个成绩结构体数组中(在写这句话的时候想到,感觉也可以直接将各科的成绩存储到一个结构体数组中,然后在进行比较,可以缩减一下代码量),然后利用冒泡循环对这个存成绩的结构体数组进行重新排序,要注意的是这个存成绩的结构体数组中元素交换位置的同时存学生各种数据结构体数组中的元素也要交换位置,这两个的数据的存储顺序是一样的,就是说一个结构体数组辅助另一个结构体数组进行排序,两个结构体需要同时发生变化。
    • 增删查改界面
      • 增——添加数据,以学号区分不同的人,姓名可以相同,但是学号每个是单独的一个,如果输入的学号已经存在,则弹窗提示,进行重新输入,直到输入通过限制条件,通过对输入的学号进行遍历,看看它是不是由纯数字组成,如果不是则弹窗提示输入格式错误,进行重新输入,直到格式正确为止。其中学生姓名不做输入格式限制,成绩同学号。完成全部输入之后进行数据保存,当前结构体人数++。如果添加的时候学号和姓名都是空的则判断为无效输入,操作无效。
      • 查——查找数据,(删除数据和修改数据都要依靠查找数据来进行操作,只有先找到结构体里面确实这个人,能对他的数据进行操作),通过输入学号或者姓名来查找一个人,在结构体数组中进行遍历来查找,找到则返回该同学在结构体数组对应的下标,然后将该同学的数据输入到屏幕上。反之,弹窗提示"查无此人"。
      • 删——删除数据进行查找,找到了就弹窗提示是否确认删除,确认删除就利用循环,从要删除的这个人在结构体数组中的下标开始,依次后面的一个数据覆盖到前面,完成后,结构体数组成员数量–。弹窗提示删除成功。
      • 改——修改数据,同样进行查找,找到了,InputBox提示输入新的数据,注意:与上面录入数据不同的是,这里新输入的学号需要先保存到临时创建的一个字符数组中,不能直接就存到要修改学生在结构体数组中对应的数据位置,因为如果是这样的话,下面在进行判断学号是否已经存在的时候就肯定是存在的了,需要在判断是否重复后,如果数据不重复,再把新输入的学号赋给要修改的变量,还需要注意的是:如果用户输入的新学号和原来的一样是可以的,所以这里需要多加一个判断,否则也会因为检查到数据重复而不能进行下一步。
  • 普通用户
    • 显示全部数据及各种排序还有查找同上。
    • 需要注意的是:管理员用户和普通用户公用界面,例如:显示全部数据和查找的输入界面,点击返回键后的跳转需要加以判。宏定义一个全局整型变量,从哪点进来的就在这句之前给它赋一个新值,条件判断语句加以判断。
  • 缺陷
    • 数据显示无法分页,只能在有限的一个界面中最多显示17条数据。
    • 代码量还可以再优化。
    • 代码没有分开编写,全部堆在一个.cpp文件中。

代码实现

#include<stdio.h>
#include<stdlib.h>
#include<graphics.h>
#include<string.h>
#include<ctype.h>//检测字符#define RecordNums 15//结构体数组数量int NowStudentNums = 0;//当前记录人数//不使用数据结构
//用结构体数组和文件操作来实现//学生结构体定义
typedef struct Student
{char s_Num[64];//学号char s_Name[64];//姓名char s_Chinese[64];//语char s_Math[64];//数char s_English[64];//英double s_SumScore;//总分
}Student;//创建学生结构体数组
Student StuArry[RecordNums];//创建成绩结构体
typedef struct Score
{double SuScore;//subject score
}Score;//创建成绩结构体——大小同学生结构体数组
Score SoArry[RecordNums];//创建管理员结构体
typedef struct Admin
{char UserName[64];char PassWord[64];
}Admin;//创建一个管理员用户
Admin AdminUser;//显示全部数据的页面跳转标识
int FlagAI = -1;
//查询找到页面跳转标识
int FlagFPT = -1;
/*MainSteps1.先搭处图形窗口的大致形态2.逐步实现里面的内容
*//*图形界面实现
*///前置声明——查看请跳转到下面查看具体说明
void AdminPage();
void AdminSignIn();
void CommonUserPage();
void SaveInfor();
void ReadInfor();
void ShowAllInfor();
void InputInfor();
void S1mplePrint();
void AdDeSeMoPage();
void DeleteStuInfor();
int ReturnPosi();
void ModifyStudInfor();
void PrintFoudInfor();
void DeSomeStu();
void SortAcChinese();
void SortAcMath();
void SortAcEnglish();
void SortAcSumScore();
bool ScoreFormat(char PerSuSc[]);
//首页
void FirstPage()
{//只要进入程序就读取数据——获取当前NowStudentNumsReadInfor();//窗口大小initgraph(760, 760);//鼠标操作1MOUSEMSG m1;cleardevice();IMAGE picture1;loadimage(&picture1, "./firstbc.jpg", 760, 760);putimage(0, 0, &picture1);setbkmode(TRANSPARENT);setfillcolor(GREEN);//大标题char FirstTitle[20] = { "学生成绩管理系统" };settextstyle(60, 0, "黑体");outtextxy(150, 100, FirstTitle);//三个选项的背景fillrectangle(230, 445, 560, 490);fillrectangle(230, 505, 560, 550);fillrectangle(230, 565, 560, 610);setbkmode(TRANSPARENT);//三个选项的文字settextstyle(40, 0, "黑体");//三个选项char FirstSelect1[20] = { "管理员操作界面" };char FirstSelect2[20] = { "普通用户操作界面" };char FirstSelect3[20] = { "退出程序" };outtextxy(240, 450, FirstSelect1);outtextxy(240, 510, FirstSelect2);outtextxy(240, 570, FirstSelect3);//进入主界面选项操作界面while (1){m1 = GetMouseMsg();//获取鼠标操作if (m1.x >= 230 && m1.x <= 560 && m1.y >= 445 && m1.y <= 490)//管理员界面{setlinecolor(RED);rectangle(230, 445, 560, 490);if (m1.uMsg == WM_LBUTTONDOWN){//加入管理员登录AdminSignIn();}}else if (m1.x >= 230 && m1.x <= 560 && m1.y >= 505 && m1.y <= 550)//普通用户界面{setlinecolor(RED);rectangle(230, 505, 560, 550);if (m1.uMsg == WM_LBUTTONDOWN){cleardevice();CommonUserPage();}}else if (m1.x >= 230 && m1.x <= 560 && m1.y >= 565 && m1.y <= 610)//退出{setlinecolor(RED);rectangle(230, 565, 560, 610);if (m1.uMsg == WM_LBUTTONDOWN){exit(0);}}//鼠标不在上面悬停else{setlinecolor(WHITE);rectangle(230, 445, 560, 490);rectangle(230, 505, 560, 550);rectangle(230, 565, 560, 610);}}}//管理员界面
void AdminPage()
{initgraph(760, 760);//先清除一下cleardevice();//定义第二个鼠标操作MOUSEMSG m2;cleardevice();IMAGE picture1;loadimage(&picture1, "./firstbc.jpg", 760, 760);putimage(0, 0, &picture1);setfillcolor(GREEN);setbkmode(TRANSPARENT);char SecondTitle1[5] = { "管" };char SecondTitle2[5] = { "理" };char SecondTitle3[5] = { "员" };char SecondTitle4[5] = { "操" };char SecondTitle5[5] = { "作" };char SecondTitle6[5] = { "界" };char SecondTitle7[5] = { "面" };settextstyle(50, 0, "黑体");outtextxy(50, 150, SecondTitle1);outtextxy(50, 210, SecondTitle2);outtextxy(50, 270, SecondTitle3);outtextxy(50, 330, SecondTitle4);outtextxy(50, 390, SecondTitle5);outtextxy(50, 450, SecondTitle6);outtextxy(50, 510, SecondTitle7);setbkmode(TRANSPARENT);//三个选项的背景fillrectangle(230, 240, 560, 285);fillrectangle(230, 370, 560, 415);fillrectangle(230, 500, 560, 545);setbkmode(TRANSPARENT);//三个选项的文字settextstyle(40, 0, "黑体");//三个选项char SecondSelect1[20] = { "显示所有数据" };char SecondSelect2[20] = { "增删查改数据" };char SecondSelect3[20] = { "返回" };outtextxy(270, 240, SecondSelect1);outtextxy(270, 370, SecondSelect2);outtextxy(350, 500, SecondSelect3);//进入主界面选项操作界面while (1){m2 = GetMouseMsg();//获取鼠标操作if (m2.x >= 230 && m2.x <= 560 && m2.y >= 240 && m2.y <= 285){setlinecolor(RED);rectangle(230, 240, 560, 285);if (m2.uMsg == WM_LBUTTONDOWN){//显示所有数据FlagAI = 1;cleardevice();ShowAllInfor();}}else if (m2.x >= 230 && m2.x <= 560 && m2.y >= 370 && m2.y <= 415){setlinecolor(RED);rectangle(230, 370, 560, 415);if (m2.uMsg == WM_LBUTTONDOWN){//增删查改界面cleardevice();AdDeSeMoPage();}}else if (m2.x >= 230 && m2.x <= 560 && m2.y >= 500 && m2.y <= 545){setlinecolor(RED);rectangle(230, 500, 560, 545);if (m2.uMsg == WM_LBUTTONDOWN){//返回cleardevice();FirstPage();}}//鼠标不在上面悬停else{setlinecolor(WHITE);rectangle(230, 240, 560, 285);rectangle(230, 370, 560, 415);rectangle(230, 500, 560, 545);}}}//普通用户界面
void CommonUserPage()
{initgraph(760, 760);记得删//先清除一下cleardevice();//定义第二个鼠标操作MOUSEMSG m3;cleardevice();IMAGE picture1;loadimage(&picture1, "./firstbc.jpg", 760, 760);putimage(0, 0, &picture1);setbkmode(TRANSPARENT);setfillcolor(GREEN);char SecondTitle1[5] = { "普" };char SecondTitle2[5] = { "通" };char SecondTitle3[5] = { "用" };char SecondTitle4[5] = { "户" };char SecondTitle5[5] = { "操" };char SecondTitle6[5] = { "作" };char SecondTitle7[5] = { "界" };char SecondTitle8[5] = { "面" };settextstyle(50, 0, "黑体");outtextxy(50, 150, SecondTitle1);outtextxy(50, 210, SecondTitle2);outtextxy(50, 270, SecondTitle3);outtextxy(50, 330, SecondTitle4);outtextxy(50, 390, SecondTitle5);outtextxy(50, 450, SecondTitle6);outtextxy(50, 510, SecondTitle7);outtextxy(50, 570, SecondTitle8);setbkmode(TRANSPARENT);//三个选项的背景fillrectangle(230, 240, 560, 285);fillrectangle(230, 370, 560, 415);fillrectangle(230, 500, 560, 545);setbkmode(TRANSPARENT);//三个选项的文字settextstyle(40, 0, "黑体");//三个选项char ThirdSelect1[20] = { "显示所有数据" };char ThirdSelect2[20] = { "查询数据" };char ThirdSelect3[20] = { "返回" };outtextxy(270, 240, ThirdSelect1);outtextxy(310, 370, ThirdSelect2);outtextxy(350, 500, ThirdSelect3);//进入主界面选项操作界面while (1){m3 = GetMouseMsg();//获取鼠标操作if (m3.x >= 230 && m3.x <= 560 && m3.y >= 240 && m3.y <= 285)//选项1{setlinecolor(RED);rectangle(230, 240, 560, 285);if (m3.uMsg == WM_LBUTTONDOWN){//显示所有数据FlagAI = -1;cleardevice();ShowAllInfor();}}else if (m3.x >= 230 && m3.x <= 560 && m3.y >= 370 && m3.y <= 415)//选项2{setlinecolor(RED);rectangle(230, 370, 560, 415);if (m3.uMsg == WM_LBUTTONDOWN){//查询数据FlagFPT = -1;PrintFoudInfor();CommonUserPage();}}else if (m3.x >= 230 && m3.x <= 560 && m3.y >= 500 && m3.y <= 545)//选项3——返回{setlinecolor(RED);rectangle(230, 500, 560, 545);if (m3.uMsg == WM_LBUTTONDOWN){cleardevice();FirstPage();}}//鼠标不在上面悬停else{setlinecolor(WHITE);rectangle(230, 240, 560, 285);rectangle(230, 370, 560, 415);rectangle(230, 500, 560, 545);}}
}/*//功能实现//
*///录入信息——通过弹窗输入&系统自动计算总分
void InputInfor()
{//InputBox中的数字参数——限制输入内容的位数//名字可以重复但是学号不能重复//通过循环来检查是否有重复的//输入学号while (1){TCHAR InputWindow0[] = _T("请输入该学生的学号");InputBox(StuArry[NowStudentNums].s_Num, 9, InputWindow0);int FlagInput2 = 0;//计算输入的字符串长度int nums = strlen(StuArry[NowStudentNums].s_Num);//判断输入的是否是纯数字for (int i = 0; i < nums; i++){if (StuArry[NowStudentNums].s_Num[i] >= '0' && StuArry[NowStudentNums].s_Num[i] <= '9')//如果不是数字{}else{FlagInput2 = 1;HWND hwndInput2 = GetHWnd();int isok = MessageBox(hwndInput2, "输入格式有误,请重新输入", "提示", MB_OK);break;}}//判断输入的是否是纯数字for (int e = 0; e < nums; e++){if (StuArry[NowStudentNums].s_Num[e] >= '0' && StuArry[NowStudentNums].s_Num[e] <= '9')//如果不是数字{}else{FlagInput2 = 1;HWND hwndInput2 = GetHWnd();break;int isok = MessageBox(hwndInput2, "输入格式有误,请重新输入", "提示", MB_OK);}}if (FlagInput2 == 0){//判断是否输入重复int FlagInput1 = 0;for (int i = 0; i < NowStudentNums; i++){if (strcmp(StuArry[NowStudentNums].s_Num, StuArry[i].s_Num) == 0){FlagInput1 = 1;}}if (FlagInput1 == 1){HWND hwndInput1 = GetHWnd();int isok = MessageBox(hwndInput1, "该学生已经存在,请重新输入", "提示", MB_OK);}if (FlagInput1 == 0){break;}}}//输入姓名TCHAR InputWindow1[] = _T("请输入该学生的姓名");InputBox(StuArry[NowStudentNums].s_Name, 10, InputWindow1);//输入语文成绩while (1){TCHAR InputWindow2[] = _T("请输入该学生的语文成绩");InputBox(StuArry[NowStudentNums].s_Chinese, 4, InputWindow2);if (ScoreFormat(StuArry[NowStudentNums].s_Chinese))//为真跳出循环{break;}}//输入数学成绩while (1){TCHAR InputWindow3[] = _T("请输入该学生的数学成绩");InputBox(StuArry[NowStudentNums].s_Math, 4, InputWindow3);if (ScoreFormat(StuArry[NowStudentNums].s_Math))//为真跳出循环{break;}}//输入英语成绩while (1){TCHAR InputWindow4[] = _T("请输入该学生的英语成绩");InputBox(StuArry[NowStudentNums].s_English, 4, InputWindow4);if (ScoreFormat(StuArry[NowStudentNums].s_English))//为真跳出循环{break;}}//计算总分StuArry[NowStudentNums].s_SumScore =atof(StuArry[NowStudentNums].s_Chinese) +atof(StuArry[NowStudentNums].s_Math) +atof(StuArry[NowStudentNums].s_English);//保存数据SaveInfor();
}//判断输入的分数格式是否正确
bool ScoreFormat(char PerSuSc[])
{//判断输入的是否是纯数字int nums = strlen(PerSuSc);//判断输入的是否是纯数字for (int i = 0; i < nums; i++){if (PerSuSc[i] >= '0' && PerSuSc[i] <= '9')//如果不是数字{}else{HWND hwndInput5 = GetHWnd();int isok = MessageBox(hwndInput5, "输入格式有误,请重新输入", "提示", MB_OK);return false;}}return true;
}//增删查改界面
void AdDeSeMoPage()
{//鼠标操作MOUSEMSG SL;//默认将会按照总分排序initgraph(860, 760);cleardevice();IMAGE picture2;loadimage(&picture2, "./secondbc.jpg", 860, 760);putimage(0, 0, &picture2);setbkmode(TRANSPARENT);setfillcolor(GREEN);fillrectangle(690, 90, 850, 140);//增fillrectangle(690, 190, 850, 240);//删fillrectangle(690, 290, 850, 340);//查fillrectangle(690, 390, 850, 440);//改fillrectangle(690, 490, 850, 540);//清空fillrectangle(690, 590, 850, 640);//返回//表头文字部分setbkmode(TRANSPARENT);settextstyle(30, 0, "黑体");outtextxy(0, 0, "排名");outtextxy(80, 0, "学号");outtextxy(200, 0, "姓名");outtextxy(300, 0, "语文");outtextxy(400, 0, "数学");outtextxy(500, 0, "英语");outtextxy(600, 0, "总分");outtextxy(740, 0, "选项");outtextxy(740, 100, "添加");outtextxy(740, 200, "删除");outtextxy(740, 300, "查找");outtextxy(740, 400, "修改");outtextxy(740, 500, "清空");outtextxy(740, 600, "返回");//打印当前已经有的信息——记录为空的提示也在这里面S1mplePrint();//进入鼠标操作环节while (1){SL = GetMouseMsg();if (SL.x >= 690 && SL.x <= 850 && SL.y >= 90 && SL.y <= 140){setlinecolor(RED);rectangle(690, 90, 850, 140);if (SL.uMsg == WM_LBUTTONDOWN){//添加InputInfor();cleardevice();//完成操作重新载入——刷新AdDeSeMoPage();}}else if (SL.x >= 690 && SL.x <= 850 && SL.y >= 190 && SL.y <= 240){setlinecolor(RED);rectangle(690, 190, 850, 240);if (SL.uMsg == WM_LBUTTONDOWN){//删除DeSomeStu();//完成操作重新载入——刷新AdDeSeMoPage();}}else if (SL.x >= 690 && SL.x <= 850 && SL.y >= 290 && SL.y <= 340){setlinecolor(RED);rectangle(690, 290, 850, 340);if (SL.uMsg == WM_LBUTTONDOWN){FlagFPT = 1;//查询PrintFoudInfor();//完成操作重新载入——刷新AdDeSeMoPage();}}else if (SL.x >= 690 && SL.x <= 850 && SL.y >= 390 && SL.y <= 440){setlinecolor(RED);rectangle(690, 390, 850, 440);if (SL.uMsg == WM_LBUTTONDOWN){//修改ModifyStudInfor();//完成操作重新载入——刷新AdDeSeMoPage();}}else if (SL.x >= 690 && SL.x <= 850 && SL.y >= 490 && SL.y <= 540){setlinecolor(RED);rectangle(690, 490, 850, 540);if (SL.uMsg == WM_LBUTTONDOWN){//确保误删——弹窗加以提示HWND hwndDel = GetHWnd();int isok = MessageBox(hwndDel, "确认清空?", "提示", MB_OKCANCEL);if (isok == IDOK){//调用清空函数DeleteStuInfor();//完成操作重新载入——刷新AdDeSeMoPage();//弹窗提示int tips1 = MessageBox(hwndDel, "清空成功!", "提示", MB_OK);}else if (isok == IDCANCEL){//点击取消不做反应}}}else if (SL.x >= 690 && SL.x <= 850 && SL.y >= 590 && SL.y <= 640){//返回setlinecolor(RED);rectangle(690, 590, 850, 640);if (SL.uMsg == WM_LBUTTONDOWN){cleardevice();//完成操作重新载入——刷新AdminPage();//辅助测试——显示当前人数/*char temptps[5];sprintf(temptps, "%d", NowStudentNums);HWND hwndTemp = GetHWnd();int tips2 = MessageBox(hwndTemp, temptps, "提示", MB_OK);*/}}//鼠标不悬停else{setlinecolor(WHITE);rectangle(690, 90, 850, 140);//增rectangle(690, 190, 850, 240);//删rectangle(690, 290, 850, 340);//查rectangle(690, 390, 850, 440);//改rectangle(690, 490, 850, 540);//清空rectangle(690, 590, 850, 640);//返回}}
}//保存数据到文件中
void SaveInfor()
{//如果学号和姓名都不是空的才写入文件if (strlen(StuArry[NowStudentNums].s_Num) != 0 && strlen(StuArry[NowStudentNums].s_Name) != 0){FILE* fp = fopen("StudentInforFile.txt", "a");if (fp == NULL){return;}fprintf(fp, "%s\t%s\t%s\t%s\t%s\t%lf\n",StuArry[NowStudentNums].s_Num,StuArry[NowStudentNums].s_Name,StuArry[NowStudentNums].s_Chinese,StuArry[NowStudentNums].s_Math,StuArry[NowStudentNums].s_English,StuArry[NowStudentNums].s_SumScore);fclose(fp);//保存完毕人数++NowStudentNums++;}}//抹除全部数据再保存——主要用于修改功能
void SaveInforModi()
{//先删掉,但是不将人数置空所以不能调用之前的删除函数remove("StudentInforFile.txt");//如果学号和姓名都不是空的才写入文件FILE* fp = fopen("StudentInforFile.txt", "a");if (fp == NULL){return;}for (int i = 0; i < NowStudentNums; i++){if (strlen(StuArry[i].s_Num) != 0 && strlen(StuArry[i].s_Name) != 0){fprintf(fp, "%s\t%s\t%s\t%s\t%s\t%lf\n",StuArry[i].s_Num,StuArry[i].s_Name,StuArry[i].s_Chinese,StuArry[i].s_Math,StuArry[i].s_English,StuArry[i].s_SumScore);}}fclose(fp);
}//读取文件中的信息-同步到当前结构体数组中,并同步得到NowStudentNums
void ReadInfor()
{FILE* fp = fopen("StudentInforFile.txt", "r");if (fp == NULL){return;}//将文件中的数据读取到当前的结构体数组中for (int i = 0; i < RecordNums; i++){fscanf(fp, "%s\t%s\t%s\t%s\t%s\t%lf\t\n",StuArry[i].s_Num,StuArry[i].s_Name,StuArry[i].s_Chinese,StuArry[i].s_Math,StuArry[i].s_English,&StuArry[i].s_SumScore);}int FileStudentNums = 0;//辅助先得到文件中的人数//读取出文件中数据的人数个数for (int k = 0; k < RecordNums; k++){if (strlen(StuArry[k].s_Name) != 0){//当前人数——FileStudentNums不能设全局变量,否则多次读取的时候会出现问题NowStudentNums = ++FileStudentNums;}}fclose(fp);
}//彻底清空——删除文件
void DeleteStuInfor()
{//删除文件remove("StudentInforFile.txt");//置空当前人数NowStudentNums = 0;
}//通用的单纯在屏幕上的对应位置打印出结构体中的每一个元素
void S1mplePrint()
{//如果为空就不往下执行if (NowStudentNums == 0){settextstyle(50, 0, "黑体");outtextxy(200, 200, "当前记录为空!");return;}for (int q = 1; q <= NowStudentNums; q++){//顺序settextstyle(30, 0, "黑体");char Nums[5];sprintf(Nums, "%d", q);//缩放字体settextstyle(25, 0, "黑体");//学号outtextxy(80, 40 + 40 * q, StuArry[q - 1].s_Num);//姓名outtextxy(200, 40 + 40 * q, StuArry[q - 1].s_Name);//语文成绩outtextxy(300, 40 + 40 * q, StuArry[q - 1].s_Chinese);//数学成绩outtextxy(400, 40 + 40 * q, StuArry[q - 1].s_Math);//英语成绩outtextxy(500, 40 + 40 * q, StuArry[q - 1].s_English);//输出总分if (strlen(StuArry[q - 1].s_Name) != 0){outtextxy(0, 40 + 40 * q, Nums);char SuSo[20];sprintf(SuSo, "%.2f", StuArry[q - 1].s_SumScore);//小数点后保留两位outtextxy(600, 40 + 40 * q, SuSo);}}
}//显示所有数据-通用
void ShowAllInfor()
{//鼠标操作MOUSEMSG SA;initgraph(860, 760);//默认只是打印数据到屏幕上cleardevice();IMAGE picture2;loadimage(&picture2, "./secondbc.jpg", 860, 760);putimage(0, 0, &picture2);setfillcolor(GREEN);setbkmode(TRANSPARENT);fillrectangle(690, 90, 850, 140);fillrectangle(690, 190, 850, 240);fillrectangle(690, 290, 850, 340);fillrectangle(690, 390, 850, 440);fillrectangle(690, 590, 850, 640);//表头文字部分setbkmode(TRANSPARENT);settextstyle(30, 0, "黑体");outtextxy(0, 0, "排名");outtextxy(80, 0, "学号");outtextxy(200, 0, "姓名");outtextxy(300, 0, "语文");outtextxy(400, 0, "数学");outtextxy(500, 0, "英语");outtextxy(600, 0, "总分");outtextxy(700, 0, "排序方式");outtextxy(700, 100, "按语文排序");outtextxy(700, 200, "按数学排序");outtextxy(700, 300, "按英语排序");outtextxy(700, 400, "按总分排序");outtextxy(740, 600, "返回");S1mplePrint();//默认只是单纯的打印while (1){SA = GetMouseMsg();if (SA.x >= 690 && SA.x <= 850 && SA.y >= 90 && SA.y <= 140){//按语文排setlinecolor(RED);rectangle(690, 90, 850, 140);if (SA.uMsg == WM_LBUTTONDOWN){SortAcChinese();//刷新重新载入ShowAllInfor();}}else if (SA.x >= 690 && SA.x <= 850 && SA.y >= 190 && SA.y <= 240){//按数学排setlinecolor(RED);rectangle(690, 190, 850, 240);if (SA.uMsg == WM_LBUTTONDOWN){SortAcMath();//刷新重新载入ShowAllInfor();}}else if (SA.x >= 690 && SA.x <= 850 && SA.y >= 290 && SA.y <= 340){//按英语排setlinecolor(RED);rectangle(690, 290, 850, 340);if (SA.uMsg == WM_LBUTTONDOWN){SortAcEnglish();//刷新重新载入ShowAllInfor();}}else if (SA.x >= 690 && SA.x <= 850 && SA.y >= 390 && SA.y <= 440){//按照总分排setlinecolor(RED);rectangle(690, 390, 850, 440);if (SA.uMsg == WM_LBUTTONDOWN){SortAcSumScore();//刷新重新载入ShowAllInfor();}}else if (SA.x >= 690 && SA.x <= 850 && SA.y >= 590 && SA.y <= 640){//返回setlinecolor(RED);rectangle(690, 590, 850, 640);if (SA.uMsg == WM_LBUTTONDOWN){cleardevice();//判断从哪个窗口点进来的if (FlagAI == 1){AdminPage();}else if (FlagAI == -1){CommonUserPage();}}}else{setlinecolor(WHITE);rectangle(690, 90, 850, 140);rectangle(690, 190, 850, 240);rectangle(690, 290, 850, 340);rectangle(690, 390, 850, 440);rectangle(690, 590, 850, 640);}}}//返回要查找/修改/删除人所在结构体的下标
int ReturnPosi()
{//接收用户输入char ReceInput[64];TCHAR InputWindowFI[] = _T("请输入学号或者姓名进行(查找)(修改)(删除)");InputBox(ReceInput, 10, InputWindowFI);//进行循环查找,一旦相同就跳出循环for (int w = 0; w < NowStudentNums; w++){if (strcmp(StuArry[w].s_Name, ReceInput) == 0 || strcmp(StuArry[w].s_Num, ReceInput) == 0)//返回0表示两个字符串相等{return w;}}//如果没找到这人就返回-1return -1;
}//打印找到人 的信息
void PrintFoudInfor(int Position)
{//鼠标操作MOUSEMSG PFI;initgraph(860, 760);cleardevice();IMAGE picture2;loadimage(&picture2, "./secondbc.jpg", 860, 760);putimage(0, 0, &picture2);setfillcolor(GREEN);fillrectangle(690, 590, 850, 640);setbkmode(TRANSPARENT);//表头文字部分settextstyle(30, 0, "黑体");outtextxy(40, 100, "学号");outtextxy(200, 100, "姓名");outtextxy(300, 100, "语文");outtextxy(400, 100, "数学");outtextxy(500, 100, "英语");outtextxy(600, 100, "总分");outtextxy(740, 600, "返回");//打印被查找人的信息//学号outtextxy(40, 140, StuArry[Position].s_Num);//姓名outtextxy(200, 140, StuArry[Position].s_Name);//语文成绩outtextxy(300, 140, StuArry[Position].s_Chinese);//数学成绩outtextxy(400, 140, StuArry[Position].s_Math);//英语成绩outtextxy(500, 140, StuArry[Position].s_English);//输出总分char SuSo[20];sprintf(SuSo, "%.2f", StuArry[Position].s_SumScore);//小数点后保留两位outtextxy(600, 140, SuSo);while (1){PFI = GetMouseMsg();if (PFI.x >= 690 && PFI.x <= 850 && PFI.y >= 590 && PFI.y <= 640){//返回setlinecolor(RED);rectangle(690, 590, 850, 640);if (PFI.uMsg == WM_LBUTTONDOWN){cleardevice();if (FlagFPT == 1){AdDeSeMoPage();}else if (FlagFPT = -1){CommonUserPage();}}}//鼠标不在选项上else{setlinecolor(WHITE);rectangle(690, 590, 850, 640);}}
}//查询——这个负责最终的调用
void PrintFoudInfor()
{//定义一个变量用来接收下标int TempPosi = ReturnPosi();if (TempPosi == -1)//没找到{//获取窗口句柄HWND hndtipsF = GetHWnd();//用一个字符数组来总结句子int isok = MessageBox(hndtipsF, "查无此人!", "提示", MB_OK);}else//找到了——打印输出{cleardevice();PrintFoudInfor(TempPosi);}
}//修改学生信息,找到返回下标,重新给他赋值,保存,否则直接弹窗警告
void ModifyStudInfor()
{//直接套用上面查找的操作,在此基础上加一行修改前//因为需要得到要修改人在结构体数组中的位置-下标,所以不能将函数直接拿过来用,得粘贴过来//定义一个变量用来接收下标int TempModi = ReturnPosi();if (TempModi == -1)//没找到{//获取窗口句柄HWND hndtipsM = GetHWnd();//用一个字符数组来总结句子int isok = MessageBox(hndtipsM, "查无此人!", "提示", MB_OK);}else//找到了这个学生进行下面的操作{cleardevice();//鼠标操作MOUSEMSG Modi;initgraph(860, 760);IMAGE picture2;loadimage(&picture2, "./secondbc.jpg", 860, 760);putimage(0, 0, &picture2);setfillcolor(GREEN);fillrectangle(690, 590, 850, 640);//表头文字部分setbkmode(TRANSPARENT);settextstyle(50, 0, "黑体");outtextxy(40, 40, "修改前");outtextxy(40, 240, "修改后");settextstyle(30, 0, "黑体");outtextxy(40, 100, "学号");outtextxy(200, 100, "姓名");outtextxy(300, 100, "语文");outtextxy(400, 100, "数学");outtextxy(500, 100, "英语");outtextxy(600, 100, "总分");outtextxy(740, 600, "返回");outtextxy(40, 300, "学号");outtextxy(200, 300, "姓名");outtextxy(300, 300, "语文");outtextxy(400, 300, "数学");outtextxy(500, 300, "英语");outtextxy(600, 300, "总分");//打印被查找人的信息//学号outtextxy(40, 140, StuArry[TempModi].s_Num);//姓名outtextxy(200, 140, StuArry[TempModi].s_Name);//语文成绩outtextxy(300, 140, StuArry[TempModi].s_Chinese);//数学成绩outtextxy(400, 140, StuArry[TempModi].s_Math);//英语成绩outtextxy(500, 140, StuArry[TempModi].s_English);//输出总分if (strlen(StuArry[TempModi].s_Name) != 0){char SuSo1[20];sprintf(SuSo1, "%.2f", StuArry[TempModi].s_SumScore);//小数点后保留两位outtextxy(600, 140, SuSo1);}//加入输入弹窗——重新书写内容//修改学号while (1){//用于接收输入的学号,先覆盖进去char TempModiNums[64];TCHAR InputWindow0[] = _T("请输入该学生的学号");InputBox(TempModiNums, 9, InputWindow0);if (strcmp(TempModiNums,StuArry[TempModi].s_Num)==0)//如果输入的学号和本身位置的学号相同{//不作出变化,直接breakbreak;}else//如果输入的学号和本身位置的学号不同,则需要判断与整个结构体中是否有重复的{int FlagInput3 = 0;int nums = strlen(TempModiNums);//判断输入的是否是纯数字for (int i = 0; i < nums; i++){if (TempModiNums[i] >= '0' && TempModiNums[i] <= '9')//如果不是数字{}else{FlagInput3 = 1;HWND hwndInput3 = GetHWnd();int isok = MessageBox(hwndInput3, "输入格式有误,请重新输入", "提示", MB_OK);break;}}if (FlagInput3 == 0){//为什么这里新输入的学号,会显示在结构体数组中存在,//因为这是修改函数,上面输入的学号已经覆盖到了他应该取得位置,/*思路1.先别把要该的值覆盖进去,先进行判断判断完成符合条件最后再把值赋给它,思路2.将原本的学生结构体数组复制一份在新的结构体数组中遍历判断//这里选择第一种*///判断是否输入重复int FlagInput4 = 0;for (int i = 0; i < NowStudentNums; i++){if (strcmp(TempModiNums, StuArry[i].s_Num) == 0){FlagInput4 = 1;break;}}if (FlagInput4 == 1){HWND hwndInput4 = GetHWnd();int isok = MessageBox(hwndInput4, "该学生已经存在,请重新输入", "提示", MB_OK);}else if (FlagInput4 == 0){//覆盖memcpy(TempModiNums, StuArry[TempModi].s_Num, nums);break;}}}}//修改姓名TCHAR InputWindow1[] = _T("请输入该学生的姓名");InputBox(StuArry[TempModi].s_Name, 10, InputWindow1);//输入语文成绩while (1){TCHAR InputWindow2[] = _T("请输入该学生的语文成绩");InputBox(StuArry[TempModi].s_Chinese, 4, InputWindow2);if (ScoreFormat(StuArry[TempModi].s_Chinese))//为真跳出循环{break;}}//输入数学成绩while (1){TCHAR InputWindow3[] = _T("请输入该学生的数学成绩");InputBox(StuArry[TempModi].s_Math, 4, InputWindow3);if (ScoreFormat(StuArry[TempModi].s_Math))//为真跳出循环{break;}}//输入英语成绩while (1){TCHAR InputWindow4[] = _T("请输入该学生的英语成绩");InputBox(StuArry[TempModi].s_English, 4, InputWindow4);if (ScoreFormat(StuArry[TempModi].s_English))//为真跳出循环{break;}}//计算总分StuArry[TempModi].s_SumScore =atof(StuArry[TempModi].s_Chinese) +atof(StuArry[TempModi].s_Math) +atof(StuArry[TempModi].s_English);//打印被查找人的信息//学号outtextxy(40, 340, StuArry[TempModi].s_Num);//姓名outtextxy(200, 340, StuArry[TempModi].s_Name);//语文成绩outtextxy(300, 340, StuArry[TempModi].s_Chinese);//数学成绩outtextxy(400, 340, StuArry[TempModi].s_Math);//英语成绩outtextxy(500, 340, StuArry[TempModi].s_English);//输出总分-加一个限制条件if (strlen(StuArry[TempModi].s_Name) != 0){char SuSo2[20];sprintf(SuSo2, "%.2lf", StuArry[TempModi].s_SumScore);//小数点后保留两位outtextxy(600, 340, SuSo2);}//保存文件SaveInforModi();while (1){Modi = GetMouseMsg();if (Modi.x >= 690 && Modi.x <= 850 && Modi.y >= 590 && Modi.y <= 640){//返回setlinecolor(RED);setlinecolor(RED);rectangle(690, 590, 850, 640);if (Modi.uMsg == WM_LBUTTONDOWN){cleardevice();//回到增删查改界面AdDeSeMoPage();//辅助测试——显示当前人数/*char temptps[5];sprintf(temptps, "%d", NowStudentNums);HWND hwndTemp = GetHWnd();int tips2 = MessageBox(hwndTemp, temptps, "提示", MB_OK);*/}}//鼠标不悬停else{setlinecolor(WHITE);rectangle(690, 590, 850, 640);}}}
}//删除某个学生的信息
void DeSomeStu()
{//先进行查找,找到返回下标,然后依次将该下标后面的数据往前推,最后人数--//没找到就查无此人//查找// //因为要实现的功能不同,所以不能直接调用查找函数//定义一个变量用来接收下标int TempDelt = ReturnPosi();if (TempDelt == -1)//没找到{//获取窗口句柄HWND hndtipsD = GetHWnd();//用一个字符数组来总结句子int isok = MessageBox(hndtipsD, "查无此人!", "提示", MB_OK);}else//找到了,确认是否删除{//找到了就提示是否确定删除//获取窗口句柄//delete sure?HWND hndtipsDS = GetHWnd();//用一个字符数组来总结句子int isok = MessageBox(hndtipsDS, "确定删除?", "提示", MB_OKCANCEL);if (isok == IDOK){//确定删除操作//将这个元素的后一个依次迁移for (int d = TempDelt; d < NowStudentNums - 1; d++){StuArry[d] = StuArry[d + 1];}//现在的人数-1NowStudentNums--;//删除完成只是将当前结构体里面的数据清除了,但是文件中并没有作出更改//更新到文件中SaveInforModi();//用这个全部清空的函数,再对文件进行重写}else if (isok == IDCANCEL){//取消删除不执行任何操作}}}//按照语文成绩进行排序
void SortAcChinese()
{//使用冒泡排序针对语文成绩对学生进行排序//用循环将每个人的成绩都存进成绩的结构体数组for (int i = 0; i < NowStudentNums; i++){SoArry[i].SuScore = atof(StuArry[i].s_Chinese);}//对结构体进行排序//注意:当用两个结构体进行排序时,即一个结构体辅助另一个结构体进行排序时,//注意两个需要同时发生变化,两个结构体都需要发生变化,积累经验for (int r = 0; r < NowStudentNums; r++){Score TempScore;Student TempStudent;for (int j = 1; j < NowStudentNums - r; j++){if (SoArry[j - 1].SuScore < SoArry[j].SuScore){TempScore = SoArry[j];TempStudent = StuArry[j];SoArry[j] = SoArry[j - 1];StuArry[j] = StuArry[j - 1];SoArry[j - 1] = TempScore;StuArry[j - 1] = TempStudent;}}}//不用保存,默认是按照添加的顺序排序
}//按照数学成绩进行排序
void SortAcMath()
{//每次给成绩结构体数组赋值都会被重新覆盖//用循环将每个人的成绩都存进成绩的结构体数组for (int i = 0; i < NowStudentNums; i++){SoArry[i].SuScore = atof(StuArry[i].s_Math);}//对结构体进行排序//注意:当用两个结构体进行排序时,即一个结构体辅助另一个结构体进行排序时,//注意两个需要同时发生变化,两个结构体都需要发生变化,积累经验for (int t = 0; t < NowStudentNums; t++){Score TempScore;Student TempStudent;for (int j = 1; j < NowStudentNums - t; j++){if (SoArry[j - 1].SuScore < SoArry[j].SuScore){TempScore = SoArry[j];TempStudent = StuArry[j];SoArry[j] = SoArry[j - 1];StuArry[j] = StuArry[j - 1];SoArry[j - 1] = TempScore;StuArry[j - 1] = TempStudent;}}}//不用保存,默认是按照添加的顺序排序
}//按照英语成绩进行排序
void SortAcEnglish()
{//每次给成绩结构体数组赋值都会被重新覆盖//用循环将每个人的成绩都存进成绩的结构体数组for (int i = 0; i < NowStudentNums; i++){SoArry[i].SuScore = atof(StuArry[i].s_English);}//对结构体进行排序//注意:当用两个结构体进行排序时,即一个结构体辅助另一个结构体进行排序时,//注意两个需要同时发生变化,两个结构体都需要发生变化,积累经验//因为顺序是一样的,可以把两个想象成一个for (int y = 0; y < NowStudentNums; y++){Score TempScore;Student TempStudent;for (int j = 1; j < NowStudentNums - y; j++){if (SoArry[j - 1].SuScore < SoArry[j].SuScore){TempScore = SoArry[j];TempStudent = StuArry[j];SoArry[j] = SoArry[j - 1];StuArry[j] = StuArry[j - 1];SoArry[j - 1] = TempScore;StuArry[j - 1] = TempStudent;}}}//不用保存,默认是按照添加的顺序排序
}//按照总分进行排序
void SortAcSumScore()
{for (int i = 0; i < NowStudentNums; i++){Student TempStudent;for (int j = 1; j < NowStudentNums - i; j++){if (StuArry[j - 1].s_SumScore < StuArry[j].s_SumScore){TempStudent = StuArry[j];StuArry[j] = StuArry[j - 1];StuArry[j - 1] = TempStudent;}}}
}//管理员登录
void AdminSignIn()
{//打开文件将账号和密码读过来FILE* fp = fopen("AdminSignIn.txt", "r");if (fp == NULL){return;}//读取到对应的管理员结构体数组fscanf(fp, "%s\t%s\t\n", AdminUser.UserName, AdminUser.PassWord);//关闭文件fclose(fp);char ReceAcctNumber[64];TCHAR InputAcct[] = _T("请输入用户名");InputBox(ReceAcctNumber, 10, InputAcct);char ReceAcctPassWord[64];TCHAR InputPass[] = _T("请输入密码");InputBox(ReceAcctPassWord, 10, InputPass);//如果用户名和密码都正确才进度到管理员界面//否则弹窗提示错误if (strcmp(AdminUser.UserName, ReceAcctNumber) == 0 && strcmp(AdminUser.PassWord, ReceAcctPassWord) == 0){cleardevice();AdminPage();}else{HWND SignError = GetHWnd();int isok = MessageBox(SignError, "用户名或密码错误!", "提示", MB_OK);}
}int main(void)
{FirstPage();return 0;
}

C语言实现学生成绩管理系统(EasyX图形界面)相关推荐

  1. c语言学生管理系统write to a text file,语言编程学生成绩管理系统.doc

    语言编程学生成绩管理系统 c语言编程-学生成绩管理系统 #include /*引用库函数*/ #include #include #include typedef struct /*定义结构体数组*/ ...

  2. c语言编写简单的成绩管理系统,用c语言编写学生成绩管理系统

    <用c语言编写学生成绩管理系统>由会员分享,可在线阅读,更多相关<用c语言编写学生成绩管理系统(9页珍藏版)>请在人人文库网上搜索. 1.include#include#inc ...

  3. c语言程序学生成绩系统论文,c语言程序设计-学生成绩管理系统论文.doc

    c语言程序设计-学生成绩管理系统论文 C语言程序设计课程设计报告 - PAGE 11 - 中南民族大学工商学院 电子信息与计算机技术系 项目名称: 学生成绩管理系统 学生姓名: 学 号: 班 级: 指 ...

  4. 用c语言实现成绩统计的设计,c语言实现学生成绩管理系统.doc

    c语言实现学生成绩管理系统.doc 学号102128121武汉理工大学华夏学院课程设计报告书课程名称:数据结构题目:用C语言实现成绩统计程序的设计系名:信息工程系专业班级:软件工程1121姓名:指导教 ...

  5. C语言 学生成绩管理系统 带登录界面

    C语言 学生成绩管理系统 带登录界面 C语言课程设计 思路 部分展示 代码片段 C语言课程设计 先上要求: 思路 为了方便简单,直接利用结构体数组来存储学生学生,最后根据功能编写函数即可. 部分展示 ...

  6. C语言实现学生成绩管理系统(原码)

    C语言实现学生成绩管理系统(单链表实现)很详细容易理解 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdl ...

  7. 影碟管理系统c语言小学期,大连东软小学期C语言项目学生成绩管理系统代码.docx...

    大连东软小学期C语言项目学生成绩管理系统代码 /*链表版学生成绩管理系统的main函数与链表构建模块的代码*/#include #include #include struct STUDENT{ ch ...

  8. C语言编写学生成绩管理系统

    文章链接:https://codemouse.online/archives/2020-06-04-16-07-48 需求 用C语言编写学生成绩管理系统,要求该系统可 对学生操作:添加和删除操作. 可 ...

  9. c语言成绩管理系统总结分析报告,c语言下学生成绩管理系统程序设计报告

    <c语言下学生成绩管理系统程序设计报告>由会员分享,可在线阅读,更多相关<c语言下学生成绩管理系统程序设计报告(17页珍藏版)>请在人人文库网上搜索. 1.信息技术学院本科课程 ...

最新文章

  1. Linux下的TCP Wrapper机制
  2. 获取qt保存对话框中输入文本_PyQt5 输入对话框QInputDialog
  3. 申请Let's Encrypt通配符HTTPS证书(转)
  4. Apache Shiro 框架简介和下载导入
  5. 网络流与线性规划24题(写了一半,先鸽下了……)
  6. 2017韩老师计算机网络,2017年计算机等考三级网络技术辅导:计算机网络拓扑结构...
  7. java 判断文件是否打开过_【后端开发】Java中如何判断文件是否被隐藏?(代码示例)...
  8. [译] 正确实现 linkedPurchaseToken 以避免重复订阅
  9. Oracle数据库忘记用户名和密码怎么办
  10. php基础教程 第五章,php基础教程——5数据库总结_PHP教程
  11. Windows was unable to connect to wifi 电脑windows连不上路由器但是连得上手机wifi?
  12. matlab多项式除法 分式展开,多项式除法有一种处理假分式的方法叫多项式除 – 手机爱问...
  13. 熬夜整理Java面试笔试题,你还看不懂吗?
  14. 实验三 配置和实施VLAN
  15. 服务名无效。 请键入 NET HELPMSG 2185 以获得更多的帮助。
  16. 【尝鲜】无视tpm安装win11 - 任何电脑皆可安装
  17. htonl(), ntohl(), htons(), ntohs() 函数具体应用
  18. python自动获取cookie_python如何获取cookie
  19. 页游安全攻与防(转)
  20. 理解操作系统的sleep函数

热门文章

  1. 为什么出价策略会进入学习期,周期是多久。
  2. 深腾8800型超级计算机,深网|中国超级计算机TOP100榜单:联想曙光各39套并列第一...
  3. 智能电视可以安装鸿蒙操作系统吗,智能电视或将现寡头垄断,鸿蒙凭为何能“上任”?...
  4. passport策略之passport-facebook使用facebook认证
  5. 最新QQ防洪跳转网站源码 带后台 可用版本
  6. 在json或数组中利用find方法实现根据value值获取key值的过程
  7. 说说Elasticsearch Segment合并
  8. 社区化会成就无线门户下一个高峰吗?
  9. 读书笔记 如何高效学习
  10. 解决EXP-00003问题