mfc学生成绩管理系统

程序设计课程设计报告

目录
一、课程设计题目及内容
二、程序中使用的数据及主要符号说明
三、带有详细注释的自己编写的源程序
四、程序运行时的效果图
五、实验结果分析,实验收获和体会。
1、实验结果分析:
2、实验收获和体会:

一、实验内容
实验1:
(1)、设计一个学生类Student,包括数据成员:姓名、学号、二门课程(面向对象程序设计、高等数学)的成绩。
(2)、创建一个管理学生的类Management,包括实现学生的数据的增加、删除、修改、按课程成绩排序、保存学生数据到文件及加载文件中的数据等功能。
(3)、创建一个基于对话框的MFC应用程序,程序窗口的标题上有你姓名、学号和应用程序名称。使用(1)和(2)中的类,实现对学生信息和成绩的输入和管理。

(4)、创建一个单文档的MFC应用程序,读取(3)中保存的文件中的学生成绩,分别用直方图和折线方式显示所有学生某课程的成绩分布图。
在这里插入图片描述

在这里插入图片描述

二、程序中使用的数据及主要符号说明

unsigned int mID;//学号
	CString mName;//姓名
	unsigned int mAge;//年龄
	CString mAdd;//地址
	float mCpp;//c++成绩
	float mMath;//数学成绩
	CListBox m_list;//列表名
	afx_msg void OnClickedButtonAdd();//添加按钮
	afx_msg void OnClickedButtonDel();//删除按钮
	afx_msg void OnClickedButtonChange();//修改
	afx_msg void OnClickedButtonOk();//确定
	afx_msg void OnClickedButtonCancle();//取消
	
	afx_msg void OnSelchangeList1();//列表控件
	virtual BOOL OnInitDialog();//初始化对话框
	afx_msg void OnDestroy();//防止内存泄漏
	afx_msg void OnClickedButton6();
	int m_count;//记录人数
	int mSex;//性别


三、带有详细注释的自己编写的源程序

1)、设计一个学生类Student
//Student.h
#pragma once

#include<string>
//using namespace std;
#include<iostream>

enum Sex { male, female };
class Student
{
public:
	Student();//构造函数
	~Student();//析构函数

	unsigned int GetID()const
	{
		return m_num;
	}
	void SetID(unsigned int ID) { m_num = ID; };
	std::string GetName()const
	{
		return m_name;
	}
	void SetName(const std::string& name) { m_name = name; };
	Sex GetSex()const
	{
		return m_sex;
	}
	void SetSex(Sex sex) { m_sex = sex; };
	unsigned int GetAge()const
	{
		return m_age;
	}
	void SetAge(unsigned int age) { m_age = age; };
	std::string GetAdd()const
	{
		return m_add;
	}
	void SetAdd(std::string add) { m_add = add; };
	float GetCpp()const
	{
		return m_cpp;
	}
	void SetCpp(float cpp) { m_cpp = cpp; };
	float GetMath()const
	{
		return m_math;
	}
	void SetMath(float math) { m_math = math; };

	friend std::ostream& operator<<(std::ostream& os, const Student& st);
	friend std::istream& operator>>(std::istream& is, Student& st);

private:
	unsigned int  m_num;//学号
	std::string m_name;//姓名
	Sex m_sex;//性别
	unsigned int m_age;//年龄
	std::string m_add;//地址
	float m_cpp;//c++成绩
	float m_math;//数学成绩

};

//Student.cpp///

#include "pch.h"
#include "Student.h"

Student::Student()//初始化
	:m_num(0)
	, m_name("")
	, m_sex(male)
	, m_age(20)
	, m_add("")
	, m_cpp(0.0f)
	, m_math(0.0f)
{

}

Student::~Student()
{
}

std::ostream& operator<<(std::ostream& os, const Student& st)//重载函数
{
	os << "" << st.m_num;
	os << "" << st.m_name;
	os << "" <<(int )st.m_sex;
	os << "" << st.m_age;
	os << "" << st.m_add;
	os << "" << st.m_cpp;
	os << "" << st.m_math;
	return os;
}

std::istream& operator>>(std::istream& is, Student& st)
{
	is >> st.m_num;
	is >> st.m_name;
	int sex;
	is >> sex;
	st.m_sex = sex == 0 ? male : female;
	is >> st.m_age;
	is >> st.m_add;
	is >> st.m_cpp;
	is >> st.m_math;
	return is;

}2)、添加一个CStudentinfo类,包括实现学生的数据的增加、删除、修改、按课程成绩排序、保存学生数据到文件及加载文件中的数据等功能。
//Dlg.h
#pragma once
// CStudentinfo 对话框

class CStudentinfo : public CDialogEx
{
	
private:
	unsigned int mID;//学号
	CString mName;//姓名
	unsigned int mAge;//年龄
	CString mAdd;//地址
	float mCpp;//c++
	float mMath;//数学
	CListBox m_list;//列表名称
public:
	afx_msg void OnClickedButtonAdd();
	afx_msg void OnClickedButtonDel();
	afx_msg void OnClickedButtonChange();
	afx_msg void OnClickedButtonOk();
	afx_msg void OnClickedButtonCancle();
public:
	afx_msg void OnSelchangeList1();
	virtual BOOL OnInitDialog();
	afx_msg void OnDestroy();
	afx_msg void OnClickedButton6();
	int m_count;人数
private:
	int mSex;//性别
};


// CStudentinfo.cpp: 实现文件
//

#include "pch.h"
#include "EX03.h"
#include "afxdialogex.h"


#include "Student.h"
#include "CStudentinfo.h"
#include <ctime>
#include <fstream>
// CStudentinfo 对话框

IMPLEMENT_DYNAMIC(CStudentinfo, CDialogEx)

//对话框初始化
CStudentinfo::CStudentinfo(CWnd* pParent /*=nullptr*/)
	: CDialogEx(DIALOG_STUDENT, pParent)
	, mID(0)
	, mName(_T(""))
	, mAge(0)
	, mAdd(_T(""))
	, mCpp(0)
	, mMath(0)
	, mSex(0)
	, m_count(0)
{

}

// CStudentinfo 消息处理程序
//

//添加
void CStudentinfo::OnClickedButtonAdd()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(TRUE);
	if (mID > 0 && !mName.IsEmpty())
	{
		Student* pSt = new Student();
	//	pSt = nullptr;
		pSt->SetID(mID);
		pSt->SetName(std::string(mName));
		pSt->SetSex(mSex == 0 ? male : female);
		pSt->SetAge(mAge);
		pSt->SetAdd(std::string(mAdd));
		pSt->SetMath(mMath);
		pSt->SetCpp(mCpp);
		CString temp;
		temp.Format(_T("%d-%s"), mID, mName);
		m_list.AddString(temp);
		m_list.SetItemDataPtr(m_list.GetCount() - 1, pSt);

		mName = "";
		mAdd = "";
		mID =0;
		mAge = 0;
		mMath = 0;
		mCpp = 0;
		UpdateData(false);
	
	}
}
 
//删除
void CStudentinfo::OnClickedButtonDel()
{
	// TODO: 在此添加控件通知处理程序代码
	int sel = m_list.GetCurSel();//获取当前对象
	if (sel == LB_ERR)return;
	auto pSt = (Student*)m_list.GetItemDataPtr(sel);
	delete pSt;
	m_list.DeleteString(sel);
}

//修改
void CStudentinfo::OnClickedButtonChange()
{
	// TODO: 在此添加控件通知处理程序代码
	int sel = m_list.GetCurSel();//获取当前对象
	if (sel == LB_ERR)return;
	auto pSt = (Student*)m_list.GetItemDataPtr(sel);
	UpdateData(TRUE);//更新数据
	pSt->SetID(mID);
	pSt->SetName(std::string(mName));
	pSt->SetSex(mSex == 0 ? male : female);
	pSt->SetAge(mAge);
	pSt->SetAdd(std::string(mAdd));
	pSt->SetCpp(mCpp);
	pSt->SetMath(mMath);
	CString temp;
	temp.Format(_T("%d-%s"), mID, mName);
	m_list.DeleteString(sel);
	m_list.InsertString(sel, temp);
	//m_list.AddString(temp);
	//m_list.SetItemDataPtr(m_list.GetCount() - 1, pSt);
	m_list.SetItemDataPtr(sel, pSt);
	mName = "";
	mAdd = "";
	UpdateData(false);

}

//确定,保存
void CStudentinfo::OnClickedButtonOk()
{
	// TODO: 在此添加控件通知处理程序代码
	TCHAR fileName[MAX_PATH];
	GetModuleFileName(nullptr, fileName, MAX_PATH);
	CString file = fileName;
	int pos = file.ReverseFind(_T('.'));
	file = file.Left(pos + 1) + _T("txt");
	std::ofstream ofile(file, std::ios::out);
	if (ofile)
	{
		int n = m_list.GetCount();
		ofile << n << std::endl;
		for (int k = 0; k < n; ++k)
		{
			auto pSt = (Student*)m_list.GetItemDataPtr(k);
			ofile << (*pSt);
		}
	}
	ofile.close();

	CDialogEx::OnOK();
}


//取消
void CStudentinfo::OnClickedButtonCancle()
{
	// TODO: 在此添加控件通知处理程序代码
	CDialog::OnOK();
}



//列表事件
void CStudentinfo::OnSelchangeList1()
{
	// TODO: 在此添加控件通知处理程序代码
	int sel = m_list.GetCurSel();//获取当前对象
	if (sel == LB_ERR)return;
	auto pSt = (Student*)m_list.GetItemDataPtr(sel);
//数据读取
	mID = pSt->GetID();
	mName = pSt->GetName().c_str();
	mSex = pSt->GetSex() == male ? 0 : 1;
	mAge = pSt->GetAge();
	mAdd = pSt->GetAdd().c_str();
	mMath = pSt->GetMath();
	mCpp = pSt->GetCpp();
	UpdateData(false);

}

//添加额外初始化
BOOL CStudentinfo::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO:  在此添加额外的初始化 

	//读取信息
	TCHAR fileName[MAX_PATH];
	GetModuleFileName(nullptr, fileName, MAX_PATH);
	CString file = fileName;
	int pos = file.ReverseFind(_T('.'));
	file = file.Left(pos + 1) + _T("txt");
	std::ifstream ifile(file, std::ios::in);
	if (ifile)
	{
		int n = 0;
		ifile >> n;
		for (int k = 0; k < n; ++k)
		{
			Student* pSt = new Student();
			ifile >> (*pSt);
			CString temp;
			temp.Format(_T("%d-%s"),pSt->GetID(), pSt->GetName().c_str());
			m_list.AddString(temp);
			m_list.SetItemDataPtr(m_list.GetCount() - 1, pSt);
		}
	}

	return TRUE;  // return TRUE unless you set the focus to a control
				  // 异常: OCX 属性页应返回 FALSE
}

//防止内存泄漏
void CStudentinfo::OnDestroy()
{
	int n = m_list.GetCount();
	for (int k = 0; k < n; ++k)
	
		delete (Student*)m_list.GetItemDataPtr(k);

	CDialogEx::OnDestroy();

	// TODO: 在此处添加消息处理程序代码
}

//随机生成
void CStudentinfo::OnClickedButton6()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(true);
	for (int k = 0; k < m_count; ++k)
	{
		auto pSt = new Student();
		pSt->SetID(190620000 + rand() % 10000);
		TCHAR name[9];
		for (int i = 0; i < 8; ++i)
		{
			name[i] = 65 + rand() % 26;
		}
		name[8] = _T('\0');
		pSt->SetName(std::string(name));
		pSt->SetSex(rand() % 2 == 0 ? male : female);
		pSt->SetAge(17 + rand() % 4);
		pSt->SetAdd(std::string(name));
		pSt->SetMath(40.0f + rand() % 51);
		pSt->SetCpp(40.0f + rand() % 54);
		CString temp;
		temp.Format(_T("%d: %s"), pSt->GetID(), pSt->GetName().c_str());
		m_list.AddString(temp);
		m_list.SetItemDataPtr(m_list.GetCount() - 1, pSt);

	}
}

(3)、创建一个基于对话框的MFC应用程序
在这里插入图片描述

(4)、创建一个单文档的MFC应用程序,读取(3)中保存的文件中的学生成绩,分别用直方图和折线方式显示所有学生某课程的成绩分布图。

// EX03View.h: CEX03View 类的接口
//

#pragma once


class CEX03View : public CView
{
// 重写
public:
	virtual void OnDraw(CDC* pDC);  // 重写以绘制该视图
// 实现
public:
	virtual ~CEX03View();
// 生成的消息映射函数
public:
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
};

// EX03View.cpp: CEX03View 类的实现
///

#include "pch.h"
#include "framework.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#include "EX03Doc.h"
#include "EX03View.h"
#include"CStudentinfo.h"
#include "Student.h"
#include <fstream>
//
// CEX03View

// CEX03View 绘图
///

void CEX03View::OnDraw(CDC* pDC )
{
	CEX03Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: 在此处为本机数据添加绘制代码
	int counts[][5] = { {0,0,0,0,0},{0,0,0,0,0} };
	int mathCppMax[2] = { -1,1 };
	for (int k = 0; k < mMaths.GetCount(); ++k)
	{
		//处理数学数据
		int n = (int)mMaths[k] / 10 - 5;
		if (n < 0) n = 0;
		else if (n > 4) n = 4;
		++counts[0][n];
		if (mathCppMax[0] < counts[0][n]) 
			mathCppMax[0] = counts[0][n];
		//处理 C++
		n = (int)mCpps[k] / 10 - 5;
		if (n < 0) n = 0;
		else if (n > 4) n = 4;
		++counts[1][n];
		if (mathCppMax[1] < counts[1][n]) 
			mathCppMax[1] = counts[1][n];
	}
	//获取客户区矩形
	CRect rect;
	GetClientRect(&rect);
	//窗口的宽度和高度
	int w = rect.Width(), h = rect.Height() / 2;
	//画分割线
	pDC->MoveTo(0, h);
	pDC->LineTo(w, h);
	//显示标题文本
	CRect rt(0, 0, w, 20);
	pDC->DrawText(_T("数学成绩统计分布图"), rt, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
	rt = CRect(0, h, w, h + 20);
	pDC->DrawText(_T("C++成绩统计分布图"), rt, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
	//设置画笔
	CPen pen;
	pen.CreatePen(PS_SOLID, 2, RGB(0x00, 0x00, 0xFF));
	auto oldPen = pDC->SelectObject(&pen);
	//设置阴影画刷
	CBrush brush0;
	brush0.CreateHatchBrush(HS_BDIAGONAL, RGB(0x00, 0x12, 0x7C));
	CBrush brush1;
	brush1.CreateHatchBrush(HS_FDIAGONAL, RGB(0x00, 0x12, 0x7C));
	//折线段数据
	CPoint pts[2][5];
	//每个矩形的宽度及每个人的高度
	int dw = 80, dh[2] = { (h - 20) / mathCppMax[0], (h - 20) / mathCppMax[1] };
	//设置起始位置
	int x = (w - 5 * dw) / 2;
	//画矩形图
	for (int k = 0; k < 5; ++k)
	{
		if (k % 2 == 0) pDC->SelectObject(&brush0);
		else pDC->SelectObject(&brush1);
		for (int i = 0; i < 2; ++i)
		{
			int y = (i + 1) * h - dh[i] * counts[i][k];
			rt = CRect(x, (i + 1) * h, x + dw, y);
			pDC->Rectangle(rt);
			CString temp;
			temp.Format(_T("%d人"), counts[i][k]);
			pDC->DrawText(temp, rt, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
			pts[i][k].x = x + dw / 2;
			pts[i][k].y = y;
		}
		x += dw;
	}
	//画折线段
	CPen redPen;
	redPen.CreatePen(PS_SOLID, 3, RGB(0xFF, 0x00, 0x00));
	pDC->SelectObject(&redPen);
	for (int k = 0; k < 2; ++k) pDC->Polyline(pts[k], 5);
	pDC->SelectObject(oldPen);

}


// CEX03View 消息处理程序
void CEX03View::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	CView::OnLButtonDown(nFlags, point);
	
		
		CStudentinfo dlg;
		if (dlg.DoModal() == IDOK)
		{
			//读取信息
			TCHAR fileName[MAX_PATH];
			GetModuleFileName(nullptr, fileName, MAX_PATH);
			CString file = fileName;
			int pos = file.ReverseFind(_T('.'));
			file = file.Left(pos + 1) + _T("txt");
			std::ifstream ifile(file, std::ios::in);
			mMaths.RemoveAll();
			mCpps.RemoveAll();
			if (ifile)
			{
				int n = 0;
				ifile >> n;
				for (int k = 0; k < n; ++k)
				{
					Student* pSt = new Student();
					ifile >> (*pSt);
					mMaths.Add(pSt->GetMath());
					mCpps.Add(pSt->GetCpp());
				}
			}
		}
}



四、程序运行时的效果图

在这里插入图片描述

在这里插入图片描述

五、实验结果分析,实验收获和体会。
1、实验结果分析:
(1)新建了Students.h头文件存储学生类
(2)将单文档与管理系统关联起来,使得在管理系统界面能够实现绘图功能。
(3)绘制了单文档的按钮,以及增加相应命令。
2、实验收获和体会:
(1)熟练使用UpdateDate函数进行界面数据更改与读入。
(2)对如listbox等控件的使用有了深层次的理解
(3)对listbox的各项函数、、sort函数等的使用的更加得心应手。
(4)领悟了char与CString在调用时的区别,以及掌握了将浮点型转化为字符型的方法。
(5)能够更加熟练的运用文件输入输出流对数据进行输入输出。
(7)对单文档的绘图功能有了一定的了解。

自我评分:91

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值