《面向对象程序设计实训》
课程设计报告
得分:
学期:
专业:
班级:
学号:
姓名:
一.课程设计目的与基本要求
1. 课程设计要求和目标
课程的主要目标是:(1) 包含数据表示的数据,伪代码或程序流程图,算法的设计方法程序结构等技术说明,功能测试的输入输出界面截图等;(2) 掌握面向对象程序设计的基本方法和步骤;(3) 通过独立完成一个综合应用程序的开发,培养学生实践动手技能,提高学生分析问题和解决问题的能力。
二.开发环境
1.开发工具:vs2022,dev。
2.运行环境:windows7,安装有office办公软件,压缩软件7z。
3.计算机配置要求:内存512M以上,硬盘40G以上,显示器和显卡必须支持1024*768,75HZ,24位真彩显示。
三.系统
1.系统的功能模块:
1) 能够从屏幕上读取一个学生的信息并将其存入数据文件中。
2)能将指定信息从文件中删除。
3)能够按编号、姓名对学生的信息进行检索并将检索结果显示在屏幕上。
4)可以统计全部学生总成绩及其在班上排名。
5)能够统计各科的平均成绩及及格率。
6)要求有错误提示功能,如性别只能输入男 女,输入错误提示重新输入。如果检索不到相应四.系统程序源代码(每页不少于50行)
五.系统测试报告
main.cpp
#include
#include "student.h"
using namespace std;
void menu(){
cout<<"****欢迎进入学生信息管理系统****"< cout<<"* 1.读取学生信息文件 *"< cout<<"* 2.保存学生信息文件 *"< cout<<"* 3.添加学生信息 *"< cout<<"* 4.删除学生信息 *"< cout<<"* 5.修改学生信息 *"< cout<<"* 6.查询学生信息 *"< cout<<"* 7.显示全部学生信息 *"< cout<<"* 8.各科信息 *"< cout<<"* 9.学生成绩占比 *"< cout<<"* 0.退出学生信息 *"< cout<<"********************************"< } int main(int argc, char* argv[]) { Student stu; int choice; char str[20]; menu(); do { cout << "请输入指令:"; cin >> choice; while (!cin) //判断输入的是否是正确的选项 { cin.clear(); //清空cin流 cin >> str; //赋值错误输入到str数组 cout << "请输入正确的指令:" << endl; cin >> choice; } switch (choice) { case 1: stu.readFile(); break; case 2: stu.saveToFile(); break; case 3: stu.logon(); break; case 4: stu.deleteBy(); break; case 5: stu.modify(); break; case 6: stu.Query(); break; case 7: stu.Show(); break; case 8: stu.studyInfo(); break; case 9: stu.scoreRate(); break; case 0: break; default: cout << "请输入正确的选项!" << endl; menu(); break; } } while (choice); return 0; } student.cpp #include "student.h" #include #include #include using namespace std; string filename("student_info"); void show(student* p); Student::Student() { head = new student; head->stu_id = 0; head->stu_name = "No name"; head->stu_next = NULL; } Student::~Student() { student* p = head; student* q = NULL; while (p) { q = p; p = q->stu_next; delete q; } } //注册函数 void Student::logon() { student tmp; double temp; cout << "学号(0结束输入):"; cin >> tmp.stu_id; while (tmp.stu_id) { if (findById(tmp.stu_id) == NULL) { bool tag = true; cout << "姓名:"; cin >> tmp.stu_name; cout << "年龄:"; cin >> tmp.stu_age; while(tag){ cout << "性别:"; cin >> tmp.stu_sex; if(tmp.stu_sex=="男"||tmp.stu_sex=="女") { tag=false; } else{ cout<<"输入性别有误,请重新输入"< } } // 初始化结构体中的总成绩 tmp.ave = 0; tmp.total = 0; cout << "语文成绩:"; cin >> tmp.stu_ywcj; tmp.total+=tmp.stu_ywcj; cout << "高数成绩:"; cin >> tmp.stu_gscj; tmp.total+=tmp.stu_gscj;; cout << "英语成绩:"; cin >> tmp.stu_yycj; tmp.total+=tmp.stu_yycj; // 计算平均成绩 tmp.ave = tmp.total/3; insert(tmp); } else { cout << "重复的学号:" << tmp.stu_id << endl; } cout << "学号(0结束输入):"; cin >> tmp.stu_id; } } //查找函数 void Student::Query() const { int select; unsigned id; string name; string sex; string email; student* p; cout << "1.按学号查询n2.按姓名查询n0.返回n"; cin >> select; switch (select) { case 1: cout << "请输入要查找的学号:"; cin >> id; if ((p = findById(id))) { show(p->stu_next); } else { cout << "没有找到输入的学号!" << endl; } break; case 2: cout << "请输入要查找的姓名:"; cin >> name; if ((p = findByName(name))) { show(p->stu_next); } break; case 0: return; default: cout << "查找失败,请重新选择查找的方式!" << endl; } } student* Student::findByName(const string& name) const { student* p; for (p = head; p->stu_next; p = p->stu_next) { if (p->stu_next->stu_name == name) { return p; } } cout << "没有找到输入的姓名!" << endl; return NULL; } student* Student::findById(unsigned id) const { student* p; for (p = head; p->stu_next; p = p->stu_next) { if (p->stu_next->stu_id == id) { return p; } } return NULL; } //删除函数 void Student::deleteBy() { int select; unsigned id; string name; cout << "1.按学号删除n2.按姓名删除n0.返回n"; cin >> select; switch (select) { case 1: cout << "请输入您要删除的学号:"; cin >> id; deleteById(id); break; case 2: cout << "请输入与您要删除的姓名:"; cin >> name; deleteByName(name); break; case 0: return; default: cout << "删除失败,请重新选择删除的方式!" << endl; } } bool Student::deleteById(unsigned& id) { student* p = NULL; student* q = NULL; p = findById(id); if (p == NULL) { cout << "没有找到学号是:"" << id << ""的学生,删除失败!" << endl; return false; } q = p->stu_next; p->stu_next = q->stu_next; delete q; cout << "成功删除学号为:"" << id << ""的学生的信息" << endl; return true; } bool Student::deleteByName(string& name) { student* p = NULL; student* q = NULL; p = findByName(name); if (p == NULL) { cout << "没有找到姓名为:"" << name << ""的学生,删除失败!" << endl; return false; } q = p->stu_next; p->stu_next = q->stu_next; delete q; cout << "成功删除姓名为:"" << name << ""的信息n"; return true; } //修改函数 void Student::modify() { int select; cout << "1.按学号修改n2.按姓名修改n0.返回n"; cin >> select; switch (select) { case 1: if (modifyById()) { cout << "修改成功!n"; } break; case 2: if (modifyByName()) { cout << "修改成功!n"; } break; case 0: return; default: cout << "修改失败,请重新选择修改的方式!" << endl; break; } } bool Student::modifyById() { student* p = NULL; unsigned id; cout << "请输入要修改的学号:" << endl; cin >> id; p = findById(id); if (p == NULL) { cout << "没有找到学号是:"" << id << ""的学生,修改失败!n"; return false; } createByStdin(1, *(p->stu_next)); return true; } bool Student::modifyByName() { student* p; string name; cout << "请输入您要修改的姓名:"; cin >> name; p = findByName(name); if (p == NULL) { cout << "没有找到姓名为:"" << name << ""的学生,修改失败!n"; return false; } createByStdin(2, *(p->stu_next)); return true; } student* Student::createByStdin(int model, student& tmp) { if (model == 1) { cout << "学号:"; cin >> tmp.stu_id; } if (model == 2) { cout << "姓名:"; cin >> tmp.stu_name; } //初始化结构体中的总成绩和平均成绩 tmp.ave = 0; tmp.total = 0; cout << "年龄:"; cin >> tmp.stu_age; cout << "性别:"; cin >> tmp.stu_sex; cout << "语文成绩:"; cin >> tmp.stu_ywcj; tmp.total += tmp.stu_ywcj; cout << "高数成绩:"; cin >> tmp.stu_gscj; tmp.total += tmp.stu_gscj; cout << "英语成绩:"; cin >> tmp.stu_yycj; //当修改成绩时,总成绩和平均成绩也发生变化 tmp.total += tmp.stu_yycj; tmp.ave = tmp.total/3; return &tmp; } //文件操作函数 void Student::saveToFile() { string new_file; cout << "请输入要保存的文件名:"; cin >> new_file; fstream file; file.open(new_file.c_str(), ios::out); if (file.bad()) { cout << "文件打开失败!" << endl; return; } int len = headCount(); file << len << endl; student* pHead = head->stu_next; while (pHead != NULL) { file << pHead->stu_id << endl; file << pHead->stu_name << endl; file << pHead->stu_sex << endl; file << pHead->stu_age << endl; file << pHead->stu_ywcj << endl; file << pHead->stu_gscj << endl; file << pHead->stu_yycj << endl; file << pHead->total << endl; file << pHead->ave << endl; pHead = pHead->stu_next; } file.close(); cout << "保存成功!" << endl; filename = new_file; return; } void Student::readFile() { string new_file; cout << "请输入要读取的文件名:"; cin >> new_file; fstream file; file.open(new_file.c_str(), ios::in); if (file.bad()) { cout << "文件打开失败!" << endl; return; } int len = 0; file >> len; while (!len) { cout << "文件数据异常!" << endl; return; } student pHead; file.get(); while (len--) { file >> pHead.stu_id; file >> pHead.stu_name; file >> pHead.stu_sex; file >> pHead.stu_age; file >> pHead.stu_ywcj; file >> pHead.stu_gscj; file >> pHead.stu_yycj; file >> pHead.total; file >> pHead.ave; insert(pHead); } file.close(); cout << "文件读入成功!" << endl; filename = new_file; return; } bool Student::insert(const student& astu) { student* newnode = NULL; student* p = head; if (p->stu_next == NULL) //当没有下一个堆,这新建一个堆来存储数据 { p->stu_next = new student(astu); //用传入的已修改结构初始化 p->stu_next->stu_next = NULL; //NULL处理再下一个堆 return true; } while (p->stu_next) //当存在下一个堆 { if (p->stu_next->stu_id == astu.stu_id) //判重 { cout << "学号重复,插入失败!" << endl; return false; } if (p->stu_next->stu_id > astu.stu_id) //如果下一个堆的id大于传入的id { newnode = new student(astu); //newnode指向初始修改结构 newnode->stu_next = p->stu_next; p->stu_next = newnode; return true; } p = p->stu_next; } p->stu_next = new student(astu); p->stu_next->stu_next = NULL; return true; } //显示函数 void Student::Show() const { student* p = NULL; cout << "--------------------------------------------" << endl; for (p = head->stu_next; p; p = p->stu_next) { show(p); } cout << "--------------------------------------------" << endl; } void show(student* p) { cout << " 学号:" << p->stu_id << " 姓名: " << p->stu_name << " 年龄: " << p->stu_age << " 性别: "; cout << p->stu_sex << " 语文成绩: " << p->stu_ywcj << " 高数成绩: " << p->stu_gscj << endl; cout << " 英语成绩: " << p->stu_yycj << " 总成绩: " << p->total << " 平均成绩: " << p->ave << endl; } void Student::getShow(unsigned id) { cout << "请稍等......" << endl; Sleep(2000); system("cls"); student* p = NULL; cout << "--------------------------------------------" << endl; if ((p = findById(id))) { show(p->stu_next); } else { cout << "输入的学号有误,请重新输入" << endl; } cout << "--------------------------------------------" << endl; } //统计各科的平均成绩和及格率 void Student::studyInfo() { double chineseAve = 0, mathAve = 0, englishAve = 0; double pass; // 达到及格线的个数 int num; //用于表示文件中学生信息的个数 double sum; //用于统计某一科目的总成绩,用于计算平均成绩 student* p = NULL; num = headCount(); //统计语文达到及格线的个数及计算及格率 for(sum = 0,pass = 0,p = head->stu_next;p;p = p->stu_next) { sum += p->stu_ywcj; if(p->stu_ywcj >= 60) { pass++; } } cout << "-------------------------------------" << endl; cout << "语文的及格率为:" << 100*(pass/num) << "%" << endl; cout << "语文的平均成绩为:" << sum/num << endl; //统计高数达到及格线的个数及计算及格率 for(sum = 0,pass = 0,p = head->stu_next;p;p = p->stu_next) { sum += p->stu_gscj; if(p->stu_gscj >= 60) { pass++; } } cout << "-------------------------------------" << endl; cout << "高数的及格率为:" << 100*(pass/num) << "%" << endl; cout << "高数的平均成绩为:" << sum/num << endl; //统计英语达到及格线的个数及计算及格率 for(sum = 0,pass = 0,p = head->stu_next;p;p = p->stu_next) { sum += p->stu_yycj; if(p->stu_yycj >= 60) { pass++; } } cout << "-------------------------------------" << endl; cout << "英语的及格率为:" << 100*(pass/num) << "%" << endl; cout << "英语的平均成绩为:" << sum/num << endl; cout << "-------------------------------------" << endl; } //显示学生各科成绩占比 void Student::scoreRate() { student* p = NULL; int num = headCount(); double num1, num2, num3, num4, num5, num6, num7, num8, num9, num10; cout<<"语文成绩比例图:"<< endl << endl; cout<<"90~100分 "; for(p = head->stu_next,num1=0;p;p = p->stu_next){ if(p->stu_ywcj>=90){ cout<<"**"; num1++; } } cout << " " << 100*(num1/num) << "%"; cout< for(p = head->stu_next,num2=0;p;p = p->stu_next){ if(p->stu_ywcj>=80&&p->stu_ywcj<90){ cout<<"**"; num2++; } } cout << " " << 100*(num2/num) << "%"; cout< for(p = head->stu_next,num3=0;p;p = p->stu_next){ if(p->stu_ywcj>=70&&p->stu_ywcj<80){ cout<<"**"; num3++; } } cout << " " << 100*(num3/num) << "%"; cout< for(p = head->stu_next,num4=0;p;p = p->stu_next){ if(p->stu_ywcj>=60&&p->stu_ywcj<70){ cout<<"**"; num4++; } } cout << " " << 100*(num4/num) << "%"; cout< for(p = head->stu_next,num5=0;p;p = p->stu_next){ if(p->stu_ywcj>=50&&p->stu_ywcj<60){ cout<<"**"; num5++; } } cout << " " << 100*(num5/num) << "%"; cout< for(p = head->stu_next,num6=0;p;p = p->stu_next){ if(p->stu_ywcj>=40&&p->stu_ywcj<50){ cout<<"**"; num6++; } } cout << " " << 100*(num6/num) << "%"; cout< for(p = head->stu_next,num7=0;p;p = p->stu_next){ if(p->stu_ywcj>=30&&p->stu_ywcj<40){ cout<<"**"; num7++; } } cout << " " << 100*(num7/num) << "%"; cout< for(p = head->stu_next,num8=0;p;p = p->stu_next){ if(p->stu_ywcj>=20&&p->stu_ywcj<30){ cout<<"**"; num8++; } } cout << " " << 100*(num8/num) << "%"; cout< for(p = head->stu_next,num9=0;p;p = p->stu_next){ if(p->stu_ywcj>=10&&p->stu_ywcj<20){ cout<<"**"; num9++; } } cout << " " << 100*(num9/num) << "%"; cout< for(p = head->stu_next,num10=0;p;p = p->stu_next){ if(p->stu_ywcj<10){ cout<<"**"; num10++; } } cout << " " << 100*(num10/num) << "%"; cout<< endl << "------------------------------------------------------" << endl << endl; cout<<"高数成绩比例图:"<< endl << endl; cout<<"90~100分 "; for(p = head->stu_next,num1=0;p;p = p->stu_next){ if(p->stu_gscj>=90){ cout<<"**"; num1++; } } cout << " " << 100*(num1/num) << "%"; cout< for(p = head->stu_next,num2=0;p;p = p->stu_next){ if(p->stu_gscj>=80&&p->stu_gscj<90){ cout<<"**"; num2++; } } cout << " " << 100*(num2/num) << "%"; cout< for(p = head->stu_next,num3=0;p;p = p->stu_next){ if(p->stu_gscj>=70&&p->stu_gscj<80){ cout<<"**"; num3++; } } cout << " " << 100*(num3/num) << "%"; cout< for(p = head->stu_next,num4=0;p;p = p->stu_next){ if(p->stu_gscj>=60&&p->stu_gscj<70){ cout<<"**"; num4++; } } cout << " " << 100*(num4/num) << "%"; cout< for(p = head->stu_next,num5=0;p;p = p->stu_next){ if(p->stu_gscj>=50&&p->stu_gscj<60){ cout<<"**"; num5++; } } cout << " " << 100*(num5/num) << "%"; cout< for(p = head->stu_next,num6=0;p;p = p->stu_next){ if(p->stu_gscj>=40&&p->stu_gscj<50){ cout<<"**"; num6++; } } cout << " " << 100*(num6/num) << "%"; cout< for(p = head->stu_next,num7=0;p;p = p->stu_next){ if(p->stu_gscj>=30&&p->stu_gscj<40){ cout<<"**"; num7++; } } cout << " " << 100*(num7/num) << "%"; cout< for(p = head->stu_next,num8=0;p;p = p->stu_next){ if(p->stu_gscj>=20&&p->stu_gscj<30){ cout<<"**"; num8++; } } cout << " " << 100*(num8/num) << "%"; cout< for(p = head->stu_next,num9=0;p;p = p->stu_next){ if(p->stu_gscj>=10&&p->stu_gscj<20){ cout<<"**"; num9++; } } cout << " " << 100*(num9/num) << "%"; cout< for(p = head->stu_next,num10=0;p;p = p->stu_next){ if(p->stu_gscj<10){ cout<<"**"; num10++; } } cout << " " << 100*(num10/num) << "%"; cout<< endl << "------------------------------------------------------" << endl << endl; cout<<"英语成绩比例图:"<< endl << endl; cout<<"90~100分 "; for(p = head->stu_next,num1=0;p;p = p->stu_next){ if(p->stu_yycj>=90){ cout<<"**"; num1++; } } cout << " " << 100*(num1/num) << "%"; cout< for(p = head->stu_next,num2=0;p;p = p->stu_next){ if(p->stu_yycj>=80&&p->stu_yycj<90){ cout<<"**"; num2++; } } cout << " " << 100*(num2/num) << "%"; cout< for(p = head->stu_next,num3=0;p;p = p->stu_next){ if(p->stu_yycj>=70&&p->stu_yycj<80){ cout<<"**"; num3++; } } cout << " " << 100*(num3/num) << "%"; cout< for(p = head->stu_next,num4=0;p;p = p->stu_next){ if(p->stu_yycj>=60&&p->stu_yycj<70){ cout<<"**"; num4++; } } cout << " " << 100*(num4/num) << "%"; cout< for(p = head->stu_next,num5=0;p;p = p->stu_next){ if(p->stu_yycj>=50&&p->stu_yycj<60){ cout<<"**"; num5++; } } cout << " " << 100*(num5/num) << "%"; cout< for(p = head->stu_next,num6=0;p;p = p->stu_next){ if(p->stu_yycj>=40&&p->stu_yycj<50){ cout<<"**"; num6++; } } cout << " " << 100*(num6/num) << "%"; cout< for(p = head->stu_next,num7=0;p;p = p->stu_next){ if(p->stu_yycj>=30&&p->stu_yycj<40){ cout<<"**"; num7++; } } cout << " " << 100*(num7/num) << "%"; cout< for(p = head->stu_next,num8=0;p;p = p->stu_next){ if(p->stu_yycj>=20&&p->stu_yycj<30){ cout<<"**"; num8++; } } cout << " " << 100*(num8/num) << "%"; cout< for(p = head->stu_next,num9=0;p;p = p->stu_next){ if(p->stu_yycj>=10&&p->stu_yycj<20){ cout<<"**"; num9++; } } cout << " " << 100*(num9/num) << "%"; cout< for(p = head->stu_next,num10=0;p;p = p->stu_next){ if(p->stu_yycj<10){ cout<<"**"; num10++; } } cout << " " << 100*(num10/num) << "%"; cout<< endl << "------------------------------------------------------" << endl << endl; } //结构数量计算函数 unsigned Student::headCount() const { unsigned cnt = 0; student* p; for (p = head->stu_next; p; p = p->stu_next, ++cnt); return cnt; } student.h #pragma once #ifndef STUDENT_H #define STUDENT_H #include #include using namespace std; typedef struct student { unsigned stu_id; string stu_name; unsigned stu_age; string stu_sex; double stu_ywcj; double stu_gscj; double stu_yycj; double total; double ave; student* stu_next; //结构链表 }student; class Student { public: Student(); ~Student(); student* createByStdin(int model, student& tmp); void logon(); //查找 void Query() const; student* findById(unsigned id) const; student* findByName(const string& name) const; //删除 void deleteBy(); bool deleteById(unsigned& id); bool deleteByName(string& name); //修改 void modify(); bool modifyById(); bool modifyByName(); //显示 void Show() const; void getShow(unsigned id); //文件操作 void saveToFile(); void readFile(); bool insert(const student& astu); //显示各科的平均成绩和及格率 void studyInfo(); //学生成绩占比 void scoreRate(); unsigned headCount() const; private: student* head; //全局的引导进入链表的指针 }; #endif 1.打开程序,进入菜单界面。 2.输入1,读取事先保存好的文件。 3.显示文件中的学生信息 4.输入3,添加学生信息。输入数据时注意数据格式,例如性别中只能输入男或女,输入其他会报错。 5.输入完所有信息后,输入2,提示保存至文件,并输入想要保存的文件名 6.按“4”,可以删除学生信息 7.按下“5”可以修改记录。有两种模式,如果按学号的话就按“1”,如果按名字的话就按“2”。 8.按下“6”,可以查询学生信息。有两种模式,如果按学号的话就按“1”,如果按名字的话就按“2”。 9.按下“8”,可以求出三科的平均分和合格率。 10.按下“9”,可以显示每个学科各分段的占比图 11.最后按下“0”退出 六.课程设计总结 这次我们所做的主要是利用c++来编一个高校学籍管理系统。对于我这么一个大二的学生来说,这么大型的软件还是第一次编写。由于过了一个暑假,c++知识有一些遗忘,在实验开始时比较迷茫。后来重新看了一下c++的课本以及一些以前编写过的程序,终于有一定的思路了。先定义一个student类,再利用类中的函数来完成题目的要求。中间再利用infile和outfile等来完成写入文件的操作。 在写程序的过程中,遇到了许许多多的困难。比如,在一开始编写将数据写入文件这段代码的时候,我花了很长的时间来编写这段代码,并且调试了多次,但是一直没办法达到要求,这让我一度很沮丧。后来,我到网上查找了相关资料,深入了解了“infile”和“outfile”这两个函数的使用,也咨询了身边的同学。经过多次的重写代码以及调试程序,终于查处了问题所在,并改正。克服困难的过程是十分痛苦的,但是当你翻过困难这座山,你就会看到前方一片光明。 通过这一次实验的磨练,让我收获颇多。有了这一次的经验,以后遇到类似的大程序时,我就不会惊慌失措。遇到程序上难以解决的困难时,我也能更加从容应对,不会像这次一样有一些惊慌失措。同时,我对c++编程有了更进一步的了解,更加能深入理解一些重要的内容。更重要的是,增强了我的自主学习能力和独立思考能力,这可以让我以后的学习可以更有效率。



