基于C++MFC的学生成绩管理系统
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_TIME
enum { IDD = IDD_DIALOG_WELCOME };
#endif
protected:
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_TIME
enum { IDD = IDD_DIALOG_LOGIN };
#endif
protected:
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:
//cstr
course() :code(""),cname(""), credit(0)
{}
course(CString _cname, CString _code, float _credit) :cname(_cname), code(_code), credit(_credit)
{}
//copy-cstr
course(const course & c)
{
cname = c.cname;
code = c.code;
credit = c.credit;
}
//dstr
virtual~course()
{}
//member of data
public:
CString code; //课程编号
CString cname; //课程名称
float credit; //课程学分
};
(4)学生的类
class student
{
public:
//cstr
student() :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];
}
//dstr
virtual~student()
{}
//member of data
public:
CString sname;//学生姓名
CString number;//学生学号
int grade[3];//假设共有三门考试科目,存储成绩的数组
float averpoint;//学生的平均学分绩点GPA
float spoint;//学生所有考试科目的总学分
};
(5)系统主界面对话框的类
// MainDlg 对话框
class MainDlg : public CDialogEx
{
DECLARE_DYNAMIC(MainDlg)
public:
MainDlg(CWnd* pParent = nullptr); // 标准构造函数
virtual ~MainDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG_MAIN };
#endif
protected:
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_TIME
enum { IDD = IDD_DIALOG_CALPOINT };
#endif
public:
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_TIME
enum { IDD = IDD_DIALOG_SEARCH };
#endif
protected:
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;
else
return 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.txt
ofstream 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中的数据》 :原文地址
上一篇: 基于java的学生成绩信息管理系统
下一篇: PHP 年龄计算函数(精确到天)_PHP