1.题目要求

学期末,班级要统计该学期考试成绩,计算每个人的学分绩点,并按照学分绩点、平均分进行排序。假设本学期开设的课程共有n门课程,每门课程均有名称、学分数;学生考试成绩的学分绩点根据考试成绩核对如下:
100分 5绩点;95-99分 4.5绩点;90-94分 4个绩点;
85-89分 3.5绩点 80-84分 3绩点,以此类推。

学生学期绩点计算方法如下:
∑(课程获取的绩点数 * 学分数)/∑学分数

提示:
1、学期所学课程的记录文件为lesson.txt,该文件共三列,第一列为课程编号,第二列为课程名称,第三列为课程学分;
2、考试成绩记录文件为grade.txt,该文件第一行为标题行,记录考生学号、姓名、考试课程;从第二行开始记录考生对应课程的考试成绩,形式如下:

请编写程序完成如下界面与功能:

1)读取课程时,对课程文件进行读取;
2)读取成绩时对成绩文件进行读取;
3)在课程信息列表中显示所有课程的基本信息;
4)在学生考试成绩信息列表中显示学生考试信息;
5)在学会考试信息列表中可对学生成绩进行修改,修改完成后,点击修改,则完成修改工作;点击保存时,将学生考试信息保存;
6)当点击查询时,对学生考试情况进行查询,弹出如下对话框

可以以学号或姓名查询,在学号或者姓名编辑框中输入学号或者姓名,点击查询,在下方的列表框中显示学生考试信息。

7)点击上个界面中的计算绩点按钮时,弹出如下界面

计算出每个学生的绩点;选择一种排序方法(生序排序或者降序排序),点击排序后,对列表中的数据进行排序;
点击保存按钮时,将排序后的结果输出到一个文件中,该文件中共有三列数据,如列表框中所示。

2.需求分析

用户利用此学生成绩管理系统,应得以实现以下主要功能:
(1)、“读取课程”:将既定lesson.txt中的课程信息读入系统,并在课程信息列表中显示出来;
(2)、“读取成绩”:将既定grade.txt中的学生成绩读入系统,并在学生考试信息列表中显示出来;
(3)、“修改”:对考试信息列表中学生成绩进行修改,并将改动保存至grade.txt;
(4)、“计算绩点”:对各学生平均绩点进行计算,在绩点统计列表中显示出来,并能根据需要,依照平均绩点进行升序或降序排列;
(5)、“查询”:能通过学生的姓名或学号,查询其各科考试成绩,并在信息查询列表中显示出来。

3.总体设计

为实现上述功能,应按照以下流程图构建系统:

主要的类:

(1)欢迎界面对话框的类

// WelcomeDlg 对话框class WelcomeDlg : public CDialogEx
{DECLARE_DYNAMIC(WelcomeDlg)public:WelcomeDlg(CWnd* pParent = nullptr);   // 标准构造函数virtual ~WelcomeDlg();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_DIALOG_WELCOME };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持DECLARE_MESSAGE_MAP()
};

(2)登录界面对话框的类

// LoginDlg 对话框class LoginDlg : public CDialogEx
{DECLARE_DYNAMIC(LoginDlg)public:LoginDlg(CWnd* pParent = nullptr);  // 标准构造函数virtual ~LoginDlg();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_DIALOG_LOGIN };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持DECLARE_MESSAGE_MAP()
public:CString m_szUsername;//Edit control控件值的变量,用于存储用户输入的“用户名”CString m_szPassward;//Edit control控件值的变量,用于存储用户输入的“密码”

(3)课程的类

class course
{public://cstrcourse() :code(""),cname(""), credit(0){}course(CString _cname, CString _code, float _credit) :cname(_cname), code(_code), credit(_credit){}//copy-cstrcourse(const course & c){cname = c.cname;code = c.code;credit = c.credit;}//dstrvirtual~course(){}//member of data
public:CString code; //课程编号CString cname; //课程名称float credit; //课程学分
};

(4)学生的类

class student
{public://cstrstudent() :sname(""), number(""), averpoint(0.0f), spoint(0.0f){grade[3] = { 0 };}student(CString _sname, CString _number, int _grade[3],float _averpoint, float _spoint) :sname(_sname), number(_number), averpoint(_averpoint), spoint(_spoint){grade[0] = _grade[0];grade[1] = _grade[1];grade[2] = _grade[2];}//dstrvirtual~student(){}//member of data
public:CString sname;//学生姓名CString number;//学生学号int grade[3];//假设共有三门考试科目,存储成绩的数组float averpoint;//学生的平均学分绩点GPAfloat spoint;//学生所有考试科目的总学分
};

(5)系统主界面对话框的类

// MainDlg 对话框class MainDlg : public CDialogEx
{DECLARE_DYNAMIC(MainDlg)public:MainDlg(CWnd* pParent = nullptr);   // 标准构造函数virtual ~MainDlg();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_DIALOG_MAIN };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持DECLARE_MESSAGE_MAP()
public:CListCtrl CourseList;//课程信息列表Listctrl的控件变量CListCtrl GradeList;//学生考试信息列表Listctrl的控件变量
CEdit m_edit;//供成绩修改用的Edit control
protected:CalPointDlg*cdlg;SearchDlg*sdlg;
public:
virtual BOOL OnInitDialog();afx_msg void OnBnClickedButtonGetcourse();//按“读取课程”时的操作afx_msg void OnBnClickedButtonGetscore();//按“读取成绩”时的操作afx_msg void OnBnClickedButtonCalculatepoint();//按“计算绩点”时的操作afx_msg void OnBnClickedButtonSearch();//按“查询”时的操作
afx_msg void OnBnClickedButtonChange();//按“修改”时的操作afx_msg void OnBnClickedButtonSave();//按“保存”时的操作afx_msg void OnLvnItemchangedListDisplayscore(NMHDR *pNMHDR, LRESULT *pResult);afx_msg void OnNMDblclkListDisplayscore(NMHDR *pNMHDR, LRESULT *pResult);afx_msg void OnEnKillfocusEditChange();//使供成绩修改用的Edit control失焦的操作
};

(6)“计算绩点”子界面对话框的类

// CalPointDlg 对话框class CalPointDlg : public CDialogEx
{DECLARE_DYNAMIC(CalPointDlg)public:CalPointDlg(CWnd* pParent = nullptr);   // 标准构造函数virtual ~CalPointDlg();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_DIALOG_CALPOINT };
#endifpublic:void calaverpoint();//计算学生平均学分绩点的函数float calgradepoint(int i);//计算单科绩点的函数
protected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持DECLARE_MESSAGE_MAP()
public:CListCtrl PointList;//绩点统计列表Listctrl的控件变量virtual BOOL OnInitDialog();afx_msg void OnBnClickedButtonSaverank();//按“保存”时的操作afx_msg void OnBnClickedRadioUp();//选择“升序排列”时的操作afx_msg void OnBnClickedRadioDown();//选择“降序排列”时的操作afx_msg void OnBnClickedButtonRamk();//按“排序”时的操作
};

(7)“查询”子界面对话框的类

// SearchDlg 对话框class SearchDlg : public CDialogEx
{DECLARE_DYNAMIC(SearchDlg)public:SearchDlg(CWnd* pParent = nullptr);   // 标准构造函数virtual ~SearchDlg();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_DIALOG_SEARCH };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持DECLARE_MESSAGE_MAP()
public:CListCtrl SearchList;//信息查询列表Listctrl的控件变量virtual BOOL OnInitDialog();afx_msg void OnBnClickedButtonSearch();//按“查询”时的操作
public:CString SearchNumber;//Edit control控件值的变量,用于存储待查询学生的“学号”CString SearchName;//Edit control控件值的变量,用于存储待查询学生的“姓名”
};

4.详细设计

具体函数代码:

(1)MFCApplication(学生成绩管理系统).cpp

BOOL CMFCApplication学生成绩管理系统App::InitInstance()
{// 自己添加部分WelcomeDlg wdlg;//建一个欢迎对话框类的对象if (wdlg.DoModal() == IDOK)//程序运行时弹出对话框,选择“登录”时执行以下操作{LoginDlg ldlg;//建一个登录对话框类的对象if (ldlg.DoModal() != IDOK)return FALSE;程序运行时弹出对话框,选择“离开”时退出系统if (ldlg.m_szUsername != TEXT("Snoopy") || ldlg.m_szPassward != TEXT("981210")){MessageBox(NULL, TEXT("用户名或密码错误"), TEXT("信息错误"), MB_OK | MB_ICONERROR);return FALSE;}//如用户名、密码均正确,按“登录”时执行以下操作MainDlg mdlg;//建一个主界面对话框的类MessageBox(NULL, TEXT("请先读取课程及成绩哦~"), TEXT("温馨提示"), MB_OK);mdlg.DoModal();//模态对话框,主界面弹出MessageBox(NULL, TEXT("欢迎您再次使用本系统!"), TEXT("THANKS"), MB_OK);return FALSE;}return FALSE;选择“退出”时,退出系统
}

(2)MainDlg.cpp//主界面对话框类中主要函数的具体实现

// MainDlg 对话框IMPLEMENT_DYNAMIC(MainDlg, CDialogEx)MainDlg::MainDlg(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_DIALOG_MAIN, pParent)
{cdlg = NULL;//初始时,将课程信息列表Listctrl的指针变量指向空sdlg = NULL;//初始时,将学生考试信息列表Listctrl的指针变量指向空
}MainDlg::~MainDlg()
{if (cdlg)//析构时,释放课程信息列表Listctrl的指针指向空间{delete cdlg;cdlg = NULL;}if (sdlg)//析构时,释放学生考试信息列表Listctrl的指针指向空间{delete sdlg;sdlg = NULL;}
}void MainDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_LIST_DISPLAYCOURSE, CourseList);DDX_Control(pDX, IDC_LIST_DISPLAYSCORE, GradeList);DDX_Control(pDX, IDC_EDIT_CHANGEGRADE, m_edit);
}BEGIN_MESSAGE_MAP(MainDlg, CDialogEx)ON_BN_CLICKED(IDC_BUTTON_GETCOURSE, &MainDlg::OnBnClickedButtonGetcourse)ON_BN_CLICKED(IDC_BUTTON_GETSCORE, &MainDlg::OnBnClickedButtonGetscore)ON_BN_CLICKED(IDC_BUTTON_CALCULATEPOINT, &MainDlg::OnBnClickedButtonCalculatepoint)ON_BN_CLICKED(IDC_BUTTON_SEARCH, &MainDlg::OnBnClickedButtonSearch)ON_BN_CLICKED(IDC_BUTTON_SAVE, &MainDlg::OnBnClickedButtonSave)ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_DISPLAYSCORE, &MainDlg::OnLvnItemchangedListDisplayscore)ON_NOTIFY(NM_DBLCLK, IDC_LIST_DISPLAYSCORE, &MainDlg::OnNMDblclkListDisplayscore)ON_EN_KILLFOCUS(IDC_EDIT_CHANGEGRADE, &MainDlg::OnEnKillfocusEditChange)ON_BN_CLICKED(IDC_BUTTON_CHANGE, &MainDlg::OnBnClickedButtonChange)
END_MESSAGE_MAP()// MainDlg 消息处理程序BOOL MainDlg::OnInitDialog()//主界面对话框初始化时的操作
{CDialogEx::OnInitDialog();// TODO:  在此添加额外的初始化m_edit.ShowWindow(SW_HIDE);CourseList.InsertColumn(0, _T("课程编号"));//课程信息列表显示的表头CourseList.SetColumnWidth(0, 80);CourseList.InsertColumn(1, _T("课程名称"));CourseList.SetColumnWidth(1, 80);CourseList.InsertColumn(2, _T("课程学分"));CourseList.SetColumnWidth(2, 80);CourseList.SetExtendedStyle(CourseList.GetExtendedStyle() | LVS_EX_GRIDLINES );//课程信息列表网格线风格GradeList.InsertColumn(0, _T("学号"));//学生考试信息列表显示的表头GradeList.SetColumnWidth(0, 70);GradeList.InsertColumn(1, _T("姓名"));GradeList.SetColumnWidth(1, 60);GradeList.InsertColumn(2, _T("C++成绩"));GradeList.SetColumnWidth(2, 70);GradeList.InsertColumn(3, _T("大学物理C1成绩"));GradeList.SetColumnWidth(3, 100);GradeList.InsertColumn(4, _T("高等数学A2成绩"));GradeList.SetColumnWidth(4, 100);GradeList.SetExtendedStyle(GradeList.GetExtendedStyle() | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);//学生考试信息列表网格线及选择后整行高亮风格return TRUE;  // return TRUE unless you set the focus to a control// 异常: OCX 属性页应返回 FALSE
}void MainDlg::OnBnClickedButtonGetcourse()//按“读取课程”时的操作
{lessonfile = "C:\\Users\\Lenovo\\Desktop\\C++\\MFCApplication(学生成绩管理系统)\\lesson.txt";if (lessonfile.empty())//如未能找到制定的lesson.txt文件{MessageBox(TEXT("课程文件读取过程有误"), TEXT("错误提示"), MB_OK);}ifstream infile;infile.open(lessonfile, ios::in);if (!infile)//如与lesson.txt建立联系失败{MessageBox(TEXT("课程文件读取过程有误"), TEXT("错误提示"), MB_OK);}char buffer[256];infile.getline(buffer, 256);//储存第一行的内容CourseList.RemoveAllGroups();veccourse.resize(3);string temcode, temcname;for (int i = 0; i<3; i++){infile >>temcode >> temcname >> veccourse[i].credit;veccourse[i].code = temcode.c_str();//string类型转CString类型veccourse[i].cname = temcname.c_str();}infile.close();CourseList.DeleteAllItems();//先清除课程信息列表Listctrl中的内容for (int i = 0; i < 3; i++)//将课程信息显示在课程信息列表中{CourseList.InsertItem(i, _T(""));CourseList.SetItemText(i, 0, veccourse[i].code);CourseList.SetItemText(i, 1, veccourse[i].cname);CString str;str.Format(_T("%f"), veccourse[i].credit);//float类型转CString类型CourseList.SetItemText(i, 2, str);}
}void MainDlg::OnBnClickedButtonGetscore()//按“读取成绩”时的操作
{// TODO: 在此添加控件通知处理程序代码gradefile = "C:\\Users\\Lenovo\\Desktop\\C++\\MFCApplication(学生成绩管理系统)\\grade.txt";if (gradefile.empty()){MessageBox(TEXT("课程文件读取过程有误"), TEXT("错误提示"), MB_OK);}ifstream infile;infile.open(gradefile, ios::in);if (!infile){MessageBox(TEXT("课程文件读取过程有误"), TEXT("错误提示"), MB_OK);}char buffer[256];infile.getline(buffer, 256);GradeList.RemoveAllGroups();string temnumber, temsname;student st;vecstudent.clear();//每次执行“读取成绩”时,都先清除掉容器原有的学生信息while(!infile.eof())//一直从grade.txt中读入,直到文件尾{temnumber = "";infile >> temnumber >> temsname >> st.grade[0]>>st.grade[1]>>st.grade[2];st.number = temnumber.c_str();st.sname = temsname.c_str();if(temnumber!="")//避免光标在最后一行下一行初保存,造成的最后一行内容显示两次vecstudent.push_back(st);}infile.close();GradeList.DeleteAllItems();int n = vecstudent.size();for (int i = 0; i < n; i++){GradeList.InsertItem(i, _T(""));GradeList.SetItemText(i, 0, vecstudent[i].number);GradeList.SetItemText(i, 1, vecstudent[i].sname);CString str;str.Format(_T("%d"), vecstudent[i].grade[0]);//int类型转CString类型GradeList.SetItemText(i, 2, str);str.Format(_T("%d"), vecstudent[i].grade[1]);GradeList.SetItemText(i, 3, str);str.Format(_T("%d"), vecstudent[i].grade[2]);GradeList.SetItemText(i, 4, str);}
}void MainDlg::OnBnClickedButtonCalculatepoint()//按“计算绩点”时的操作{// TODO: 在此添加控件通知处理程序代码if (cdlg == NULL)//非模态对话框,弹出“计算绩点”的子界面{cdlg = new CalPointDlg;cdlg->Create(IDD_DIALOG_CALPOINT);cdlg->ShowWindow(SW_SHOWNORMAL);cdlg->UpdateWindow();}else{cdlg->ShowWindow(SW_SHOWNORMAL);cdlg->UpdateWindow();}
}void MainDlg::OnBnClickedButtonSearch()//按“查询”时的操作
{// TODO: 在此添加控件通知处理程序代码MessageBox(TEXT("请输入学号或姓名进行查询~"), TEXT("温馨提示"), MB_OK);if (sdlg == NULL){sdlg = new SearchDlg;sdlg->Create(IDD_DIALOG_SEARCH);sdlg->ShowWindow(SW_SHOWNORMAL);sdlg->UpdateWindow();}else{sdlg->ShowWindow(SW_SHOWNORMAL);sdlg->UpdateWindow();}
}void MainDlg::OnNMDblclkListDisplayscore(NMHDR *pNMHDR, LRESULT *pResult)//鼠标左键双击学生考试信息列表时的操作,对Listctrl中学生成绩进行修改
{LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);// TODO: 在此添加控件通知处理程序代码NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;CRect rc;m_Row = pNMListView->iItem;//获得选中的行m_Col = pNMListView->iSubItem;//获得选中列if (pNMListView->iSubItem>1) //如果选择的是成绩子项;{GradeList.GetSubItemRect(m_Row, m_Col, LVIR_LABEL, rc);//获得子项的RECT;m_edit.SetParent(&GradeList);//转换坐标为列表框中的坐标m_edit.MoveWindow(rc);//移动Edit到RECT坐在的位置;m_edit.SetWindowText(GradeList.GetItemText(m_Row, m_Col));//将该子项中的值放在Edit控件中;m_edit.ShowWindow(SW_SHOW);//显示Edit控件;m_edit.SetFocus();//设置Edit焦点m_edit.ShowCaret();//显示光标m_edit.SetSel(-1);//将光标移动到最后}*pResult = 0;
}void MainDlg::OnEnKillfocusEditChange()使供成绩修改用的Edit control失焦的操作
{// TODO: 在此添加控件通知处理程序代码CString tem;m_edit.GetWindowText(tem);    //得到用户输入的新的内容GradeList.SetItemText(m_Row, m_Col, tem);   //设置编辑框的新内容m_edit.ShowWindow(SW_HIDE);                //应藏编辑框
}void MainDlg::OnBnClickedButtonChange()//按“修改”时的操作
{// TODO: 在此添加控件通知处理程序代码if(m_Row==-1&&m_Col==-1)MessageBox(TEXT("您未进行成绩修改"), TEXT("温馨提示"), MB_OK);else{int temgrade;temgrade = _ttoi(GradeList.GetItemText(m_Row, m_Col));//CString类型转int类型vecstudent[m_Row].grade[m_Col - 2] = temgrade;//将修改后的成绩存入容器中对应位置MessageBox(TEXT("修改成功"), TEXT("成功提示"), MB_OK);}
}void MainDlg::OnBnClickedButtonSave()//按“保存”时的操作
{// TODO: 在此添加控件通知处理程序代码MessageBox(TEXT("此功能仅适用于修改后的保存~"), TEXT("温馨提示"), MB_OK);gradefile = "C:\\Users\\Lenovo\\Desktop\\C++\\MFCApplication(学生成绩管理系统)\\grade.txt";ofstream outfile;outfile.open(gradefile, ios::out);if (!outfile){MessageBox(TEXT("文件保存过程有误"), TEXT("错误提示"), MB_OK);}outfile << "学号 姓名  C++成绩 大学物理C1成绩    高等数学A2成绩" << endl;size_t n = vecstudent.size();string temsname, temnumber;for (size_t i = 0; i<n; i++){temsname = CT2A(vecstudent[i].sname);//CString类型转string类型temnumber = CT2A(vecstudent[i].number);outfile << temnumber << "   " << temsname <<" " << vecstudent[i].grade[0] << setw(16) << vecstudent[i].grade[1] << setw(30) << vecstudent[i].grade[2]<< endl;}outfile.close();MessageBox(TEXT("文件保存成功"), TEXT("成功提示"), MB_OK);
}

(3)CalPointDlg.cpp//“计算绩点”子界面对话框类中主要函数的具体实现

extern vector<student> vecstudent;
extern vector<course> veccourse;
string rankfile;
int ranktype = 0;//用于判断依据绩点排序类型(升序排列、降序排列)的变量// CalPointDlg 对话框IMPLEMENT_DYNAMIC(CalPointDlg, CDialogEx)CalPointDlg::CalPointDlg(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_DIALOG_CALPOINT, pParent)
{}CalPointDlg::~CalPointDlg()
{}void CalPointDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_LIST_POINT, PointList);
}BEGIN_MESSAGE_MAP(CalPointDlg, CDialogEx)ON_BN_CLICKED(IDC_BUTTON_SAVERANK, &CalPointDlg::OnBnClickedButtonSaverank)ON_BN_CLICKED(IDC_RADIO_UP, &CalPointDlg::OnBnClickedRadioUp)ON_BN_CLICKED(IDC_RADIO_DOWN, &CalPointDlg::OnBnClickedRadioDown)ON_BN_CLICKED(IDC_BUTTON_RAMK, &CalPointDlg::OnBnClickedButtonRamk)
END_MESSAGE_MAP()// CalPointDlg 消息处理程序
float CalPointDlg::calgradepoint(int i)//计算单科绩点的函数
{if (i == 100)return 5.0;else if (i >= 95)return 4.5;else if (i >= 90)return 4.0;else if (i >= 85)return 3.5;else if (i >= 80)return 3.0;else if (i >= 75)return 2.5;else if (i >= 70)return 2.0;else if (i >= 65)return 1.5;else if (i >= 60)return 1.0;elsereturn 0.0;
}void CalPointDlg::calaverpoint() //计算学生平均学分绩点的函数
{float scredit = veccourse[0].credit + veccourse[1].credit + veccourse[2].credit;size_t n = vecstudent.size();for (size_t t = 0; t<n; t++){for (int i = 0; i < 3; i++){vecstudent[t].spoint += calgradepoint(vecstudent[t].grade[i])* veccourse[i].credit;}vecstudent[t].averpoint = vecstudent[t].spoint / scredit;vecstudent[t].averpoint = ((float)((int)(vecstudent[t].averpoint * 100))) / 100;//使平均绩点只保留小数点后两位}
}BOOL CalPointDlg::OnInitDialog()
{CDialogEx::OnInitDialog();// TODO:  在此添加额外的初始化PointList.InsertColumn(0, _T("学号"));//绩点统计列表显示的表头PointList.SetColumnWidth(0, 70);PointList.InsertColumn(1, _T("姓名"));PointList.SetColumnWidth(1, 60);PointList.InsertColumn(2, _T("绩点"));PointList.SetColumnWidth(2, 70);PointList.SetExtendedStyle(PointList.GetExtendedStyle() | LVS_EX_GRIDLINES);calaverpoint();//计算所有学生各自的平均绩点PointList.DeleteAllItems();int n = vecstudent.size();//获取总学生数for (int i = 0; i < n; i++){PointList.InsertItem(i, _T(""));PointList.SetItemText(i, 0, vecstudent[i].number);PointList.SetItemText(i, 1, vecstudent[i].sname);CString str;str.Format(_T("%f"), vecstudent[i].averpoint);PointList.SetItemText(i, 2, str);}return TRUE;  // return TRUE unless you set the focus to a control// 异常: OCX 属性页应返回 FALSE
}void CalPointDlg::OnBnClickedRadioUp()选择“升序排列”时的操作
{// TODO: 在此添加控件通知处理程序代码ranktype = 1;
}void CalPointDlg::OnBnClickedRadioDown()选择“降序排列”时的操作
{// TODO: 在此添加控件通知处理程序代码ranktype = 2;
}void CalPointDlg::OnBnClickedButtonRamk()//按“排序”时的操作
{// TODO: 在此添加控件通知处理程序代码size_t n = vecstudent.size();for (size_t t = 0; t<n - 1; t++){for (int i = 0; i < n - t - 1; i++){if (ranktype == 1)//依据平均绩点升序排列并使存储学生信息的容器同步更新{if (vecstudent[i].averpoint < vecstudent[i + 1].averpoint){student s = vecstudent[i];;vecstudent[i] = vecstudent[i + 1];vecstudent[i + 1] = s;}}else if (ranktype == 2)//依据平均绩点降序排列并使存储学生信息的容器同步更新{if (vecstudent[i].averpoint > vecstudent[i + 1].averpoint){student s = vecstudent[i];;vecstudent[i] = vecstudent[i + 1];vecstudent[i + 1] = s;}}}}PointList.DeleteAllItems();//清除绩点统计列表中原有内容for (int i = 0; i < n; i++)//在绩点统计列表中显示出排序后的各学生平均绩点信息{PointList.InsertItem(i, _T(""));PointList.SetItemText(i, 0, vecstudent[i].number);PointList.SetItemText(i, 1, vecstudent[i].sname);CString str;str.Format(_T("%f"), vecstudent[i].averpoint);PointList.SetItemText(i, 2, str);}
}void CalPointDlg::OnBnClickedButtonSaverank()//按“排序”时的操作
{// TODO: 在此添加控件通知处理程序代码rankfile = "C:\\Users\\Lenovo\\Desktop\\C++\\MFCApplication(学生成绩管理系统)\\rank.txt";//将按已选择的排序方式排列后的学生信息输出至rank.txtofstream outfile;outfile.open(rankfile, ios::out);if (!outfile){MessageBox(TEXT("文件保存过程有误"), TEXT("错误提示"), MB_OK);}outfile << "姓名 学号  平均绩点" << endl;size_t n = vecstudent.size();string temsname, temnumber;for (size_t i = 0; i<n; i++){temsname=CT2A(vecstudent[i].sname);temnumber=CT2A(vecstudent[i].number);outfile << temsname << "    " << temnumber << setw(11) << vecstudent[i].averpoint << endl;}outfile.close();MessageBox(TEXT("文件保存成功"), TEXT("成功提示"), MB_OK);
}

(4)SearchDlg.cpp//“查询”子界面对话框类中主要函数的具体实现

extern vector<student> vecstudent;// SearchDlg 对话框IMPLEMENT_DYNAMIC(SearchDlg, CDialogEx)SearchDlg::SearchDlg(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_DIALOG_SEARCH, pParent), SearchNumber(_T(""))//初始时,待查询学生的“学号”置为空, SearchName(_T(""))//初始时,待查询学生的“姓名”置为空
{}SearchDlg::~SearchDlg()
{}void SearchDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_LIST_SEARCH, SearchList);DDX_Text(pDX, IDC_EDIT_NUMBERSEARCH, SearchNumber);DDX_Text(pDX, IDC_EDIT_NAMESEARCH, SearchName);
}BEGIN_MESSAGE_MAP(SearchDlg, CDialogEx)ON_BN_CLICKED(IDC_BUTTON_SEARCH, &SearchDlg::OnBnClickedButtonSearch)
END_MESSAGE_MAP()// SearchDlg 消息处理程序BOOL SearchDlg::OnInitDialog()
{CDialogEx::OnInitDialog();// TODO:  在此添加额外的初始化SearchList.InsertColumn(0, _T("考试科目"));//信息查询列表显示的表头SearchList.SetColumnWidth(0, 80);SearchList.InsertColumn(1, _T("成绩"));SearchList.SetColumnWidth(1, 80);SearchList.SetExtendedStyle(SearchList.GetExtendedStyle() | LVS_EX_GRIDLINES);SearchList.InsertItem(0, _T("C++"));//信息查询列表第一列显示的内容SearchList.InsertItem(1, _T("大学物理C1"));SearchList.InsertItem(2, _T("高等数学A2"));return TRUE;  // return TRUE unless you set the focus to a control// 异常: OCX 属性页应返回 FALSE
}void SearchDlg::OnBnClickedButtonSearch()//按“查询”时的操作
{// TODO: 在此添加控件通知处理程序代码int searchednumber = -1;//用于记录待查找学生是容器中第几个的变量UpdateData(TRUE);//将Edit control中的值随时更新到对应变量中int n = vecstudent.size();if (SearchNumber != ""&& SearchName == "")//如果只输入了“学号”{for (int i = 0; i < n; i++){if (SearchNumber == vecstudent[i].number) searchednumber = i;}}else if (SearchNumber == "" && SearchName != "")//如果只输入了“姓名”{for (int i = 0; i < n; i++){if (SearchName == vecstudent[i].sname) searchednumber = i;}}else if (SearchNumber != ""&& SearchName != "")//如果“学号”和“姓名”都输入了{searchednumber = -2;for (int i = 0; i < n; i++){if (SearchNumber == vecstudent[i].number){if (SearchName == vecstudent[i].sname) searchednumber = i;}}}if (searchednumber == -1)MessageBox(TEXT("您要找的学生不存在"), TEXT("错误提示"), MB_OK);else if (searchednumber == -2)MessageBox(TEXT("您输入的学号与姓名不匹配"), TEXT("错误提示"), MB_OK);Else//将查找到的学生各科考试成绩信息显示到信息查询列表中{CString str;str.Format(_T("%d"), vecstudent[searchednumber].grade[0]);SearchList.SetItemText(0, 1, str);str.Format(_T("%d"), vecstudent[searchednumber].grade[1]);SearchList.SetItemText(1, 1, str);str.Format(_T("%d"), vecstudent[searchednumber].grade[2]);SearchList.SetItemText(2, 1, str);}
}

5.上机操作

(1)、程序运行,弹出欢迎界面

(2)、按“登录”键,弹出登录界面

(3)、正确输入用户名、密码后,按“登录”进入系统(用户这部分我没有做过多拓展,仅提供了一个用户用于测试,可以根据实际需要再完善鸭)

点击“确定”后,弹出主界面

(4)、按“读取课程”,lesson.txt中的课程信息在右侧列表中显示

(5)、按“读取成绩”,grade.txt中的课程信息在下方列表中显示

(6)、选择“计算绩点”,子界面弹出

选择“升序排列”或“降序排列”后,按“排序”,列表中信息按排序后的顺序显示

排序后,按“保存”(以升序排列为例),提示保存成功

此时打开rank.txt,发现信息已存入

(7)、选择“查询”,出现温馨提示

点击“确定”,子界面弹出

输入学生学号或姓名,按“查询”,此学生成绩在下方列表中显示

(8)、双击要修改的成绩,弹出编辑框进行修改

修改后单击其它地方,列表中学生成绩信息更新

按“修改”,弹出成功提示

(9)、按“保存”,弹出温馨提示、成功提示

再次打开grade.txt,发现信息已同步修改

(10)、按“退出”,退出系统

(画外音:测试数据都是自己编哒,然后数据量比较小hhh,可以自行多搞些数据康康效果~)

参考博文:
[1]:CSDN 《VC 双击编辑ListControl中的数据》 :原文地址

基于C++MFC的学生成绩管理系统相关推荐

  1. MFC ODBC 学生成绩管理系统 示例

    目录 摘要 实验重点 程序流程图 数据库准备 本地SQL Server建表 远程MySQL建表 界面开发 登陆对话框 1. 为对话框添加图标 2. 窗体打开时自动定位焦点到第一个编辑框 3. 登录验证 ...

  2. c语言用链表实现成绩管理系统,C语言基于单链表得学生成绩管理系统

    前言 传说中讲课通俗而不庸俗,说话风流而不下流的小编又来了哦,今天的主要内容是:C语言基于单链表得学生成绩管理系统.首先给年夜家总结下为什么你们学习C语言会觉得难,尤其是对单链表这块,主要原因得是因为 ...

  3. 基于SpringBoot+Vue的学生成绩管理系统

    基于SpringBoot+Vue的学生成绩管理系统 ,已经实现了增删改查,完美的springBoot项目脚手架 ,适合学习和二次开发,课程设计 已经实现了增删改查和搜索查询所有功能,完美的spring ...

  4. 基于Web的高校学生成绩管理系统

    http://www.chinalww.com.cn 中国论文网 基于Web的高校学生成绩管理系统 asp.net+sql 2000 源程序+15000字论文(200元) 摘   要 现在已进入了信息 ...

  5. 基于javaweb+JSP+Servlet学生成绩管理系统(管理员、教师、学生)

    基于javaweb+JSP+Servlet学生成绩管理系统(管理员.教师.学生) 开发工具:eclipse/idea/myeclipse/sts等均可配置运行 适用 课程设计,大作业,毕业设计,项目练 ...

  6. 基于JavaCS架构的学生成绩管理系统

    基于 C/S 结构学生成绩管理系统 需求分析 该系统主要分配两个角色,管理员角色和学生角色.管理员的主要功能:添加用户:学生的主要功能:查询成绩.选择课程:老师的主要功能:增加课程.给学生打分. 功能 ...

  7. java基于springboot+vue的学生成绩管理系统 elementui

    在我国,基本每一个人都会经历学生时代,在学生时代大家比较看重的一点就是学生的成绩.相较过去而言,当前的学生成绩一般都是信息化的管理系统再也不是以前的那种手动管理模式.信息化的管理模式不仅可以让学生可以 ...

  8. 基于SSH实现的学生成绩管理系统

    开发语言:JAVA 开发技术:spring+springmvvc+hibernate+easyui 数据库:MYSQL 开发工具:IDEA / Eclipse 该学生成绩管理系统主要包括前台用户界面的 ...

  9. c语言成绩统计与学籍管理源码,[源码和文档分享]基于C语言的学生成绩管理系统...

    一 需求分析 假设某班有不超过40人(具体人数在程序运行时由键盘录入)参加本学期的期末考试,考试科目为语文(CN),数学(MT),英语(EN),科学(SC).编写一个学生成绩管理系统,实现对班级学生成 ...

最新文章

  1. RHEL/CentOS通用性能优化、安全配置参考
  2. Python重装时记录所有库 生成requirement 使用requirements.txt
  3. FPGA的设计艺术(11)FPGA的构建过程
  4. 【CSS进阶】CSS 颜色体系详解
  5. 任天堂新音樂遊戲上市
  6. 字段中存在空值的问题测试
  7. python数据结构算法 北京大学_北京大学公开课《数据结构与算法Python版》
  8. Go语言通过odbc驱动连接华为高斯数据库
  9. toolStrip 按钮图片大小的修改
  10. javascript 学习笔记(一)
  11. matlab 元胞调用方法你真的理解了么?
  12. 虚拟机查看cpu型号_CentOS7安装KVM虚拟机
  13. linux目录数据块,如何在Linux上列出文件的数据块?
  14. [译]如何成为一个优秀的前端工程师
  15. 《大话设计模式》笔记2
  16. DOS BAT脚本批量打开Edge网页
  17. freeswitch 解决方案之视频会议
  18. html鼠标跟踪特效,HTML5 WebGL带鼠标跟踪的月晕涟漪动画特效
  19. 1193 Eason
  20. 该网站服务器出错了怎么回事,该网站服务器出错了是什么意思(图文)

热门文章

  1. 如何让程序运行后不谈程序兼容性助手
  2. 原创 | DDD领域驱动设计第一话
  3. 【Flink基础】-- 高效学习 flink kubernetes operator 的一些建议
  4. 【微信开发第一章】SpringBoot实现微信公众号创建菜单,同步菜单功能
  5. 关于安科瑞电气安全产品在医药工业洁净厂房的电气工程设计与应用
  6. switch为什么总是出现问题?
  7. 很久以前某位大仙对petri网的总结
  8. PXE无人值守安装系统
  9. 解决adb shell root权限
  10. CSS设置表格行列,给bootstrap table设置行列单元格样式