程序设计课程设计报告
目录
一、课程设计题目及内容
二、程序中使用的数据及主要符号说明
三、带有详细注释的自己编写的源程序
四、程序运行时的效果图
五、实验结果分析,实验收获和体会。
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);
}
}
(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