两次编写管理系统心得体会
大一下学期,我正式开始学习C++,为了巩固自己所学到的知识,我开始编写我学习计算机以来第一个综合性的实验项目:图书管理系统。
在编写图书管理系统时,几乎是从一无所知开始的,犯的错误,走的弯路数不胜数,在停停写写一个月后,图书管理系统终于编写出来:
这是效果图:
然而,这个系统是在我完全没有经验的情况下编写的,存在的缺陷,BUG自然数不胜数,然而,最大的缺陷之一就是他的文件操作效率非常之低;在导师的提点之下,我在七月初进行了学生成绩管理系统的开发,设计上,两个系统非常相似,学生成管理系统就连界面都是使用了在做图书管理系统时封装好的界面类,然而,两大系统最大的不同就在于在文件操作上的不同:
在此,我将对两个系统进行对比分析:
注:因为是实验项目,所以不涉及数据库的知识。(所涉及的信息量也很小)
NO.1 存和取:
如果把硬盘里的数据比作仓库里的物品,内存比作货架上的物品,那么我在编写图书管理系统的时候,“货架上”经常是空荡荡的,每次接受到“消费者”的指令,“我”都会把物品从仓库里取出来,每次“进货”,修改数据,都直接把他们塞进仓库。
请先看看以下两段代码:
这是user类(reader类和ruder类的基类)的方法,调取读者花名册。
void user::manlist()
{
int cpbook;
ifstream fin("count\\mannumber.txt");//这样分两次打开,可避免读文件时,误改了源文件
fin>>cpbook;//从记事本读取书的数目
fin.close();
int i;
ifstream fin2("manstorage\\manlist.txt");
for( i=0;i<cpbook;i++)
{
fin2>>name>>key>>number;
cout<<"姓名:"<<setfill(' ')<<setw(10)<<name<<" 密码:"<<setfill(' ')<<setw(10)<<key<<" 学号:"<<setfill(' ')<<setw(10)<<number;
cout<<endl;
}
fin2.close();
}
int user::exactFind(int i)
{
int ctrl=0;
string nofound="呵呵,没有这个人哦~~";
string c;
char na[40];
cout<<"请输入用户名:";
cin>>na;
c.assign(na);
if(i==1||i==0)
{c=Address(c);}
if(i==2)
{c=Address5(c);}
ifstream fin3(c);
if(!fin3)
{
cout<<nofound;
ctrl=1;
}
fin3>>name;
fin3>>key;
fin3>>number;
fin3.close();
if(i==0&&ctrl==0)
{
cout<<"姓名:"<<setfill(' ')<<setw(10)<<name<<" 密码:"<<setfill(' ')<<setw(10)<<key<<" 学号:"<<setfill(' ')<<setw(10)<<number;
}
return ctrl;
}
下面是添加一名新用户操作的源代码:
这是ruler里的一个方法(Rulerdefine.cpp),增加新读者。
void Ruler::addMan(Reader & m)
{
ifstream fin("count\\mannumber.txt");//这样分两次打开,可避免读文件时,误改了源文件
fin>>cpman;//从记事本会员的数目
fin.close();//关闭记事本
for(int i=0;i<cpman;i++)
{
if(m==*man[i])
{
cout<<"already";
return;
}
}//检查新添加的会员是否已经存在(“==”号已经经过重载)
man[cpman++]=&m;//若不存在则添加一名新成员
ofstream fout("Manstorage\\manlist.txt", ios::app);
fout<<m;
fout.close();
//文件操作,将改名新成员的信息存在manlist(名单)中
string c;
c=m.getName();
cout<<c;
c=Address(c);//通过函数Address()将name拷贝并变成地址形式赋给c;
ofstream fout3(c, ios::binary);
fout3<<m;
//(下一步将借书情况写在里边,下一步要录入vector中的信息啦)
fout3.close();//每个成员的详细信息会存在一个独立的txt文件
c=m.getName();
c=Address3(c);//通过函数Address()将name拷贝并变成地址形式赋给c;
ofstream fout4(c, ios::app);
fout4.close();//每个成员的详细信息会存在一个独立的txt文件
ofstream fout2("count\\mannumber.txt", ios::binary);
fout2<<cpman;
fout2.close();//每添加一个成员计数文件mannumber就会+1
}
加粗的地方是文件操作的部分。我们可以看到,执行查找操作时,是从硬盘中调取数据,当方法调用结束之后,内存将会被回收,执行增加用户的操作时,首先调取一个存储用户数的文件读取已经登记在册的用户数量这个数据,之后将用户信息单独储存在一个文件,包括用户的基本信息和所借的书,然后再将用户的部分信息存在一个统一的文件里(很麻烦)。这样的操作相当繁琐,因为几乎是只要对用户信息一点点的修改都需要修改多个文件,这样是非常容易出错滴……
现在,我们来看看在学生成绩系统中,我们是怎样进行文件操作的:
void main()
{
int choose;//界面选择(选项)
char choose2;//界面选择(是否退出)
winDesign line;//画直线
windowDesigner window(line);//画方框
Browse Gradeone;//一年级
Browse Gradetwo;//二年级
Browse Teacher;//教师
student Student(window);
teacher Ateacher(window);
gradeone boy(window);//一年级新生
gradetwo boy2(window);
int Count1;//一年级人数计数器
int Count2;//二年级人数计数器
int CountTeacher;//教师人数计数器
vector<Browse> gradeOneList;//容器一年级
vector<Browse> gradeTwoList;//容器二年级
vector<Browse> TeacherList;//容器教师
//读取老师数据
ifstream finteachercount("teacherlist\\count.txt");//从硬盘中读取信息
finteachercount>>CountTeacher;//读取人数信息
finteachercount.close();//关闭
ifstream finteacher("teacherlist\\listTeacher.txt");//读取学生详细信息
for(int i = 0;i<CountTeacher;i++)//
{
finteacher>>Teacher;
TeacherList.push_back(Teacher);//将信息放入容器
}
finteacher.close();//关闭
//读取大一学生数据
ifstream fincountOne("gradeonestudent\\count.txt");//从硬盘中读取信息
fincountOne>>Count1;//读取人数信息
fincountOne.close();//关闭
ifstream finGradeone("gradeonestudent\\list1.txt");//读取学生详细信息
for(int i = 0;i<Count1;i++)//
{
finGradeone>>Gradeone;
gradeOneList.push_back(Gradeone);//将信息放入容器
}
finGradeone.close();//关闭
//读取大二学生数据:
ifstream fincountTwo("gradetwostudent\\count.txt");//从硬盘中读取信息
fincountTwo>>Count2;//读取人数信息
fincountTwo.close();//关闭
ifstream finGradetwo("gradetwostudent\\list2.txt");//读取学生详细信息
for(int i = 0;i<Count2;i++)//
{
finGradetwo>>Gradetwo;
gradeTwoList.push_back(Gradetwo);//将信息放入容器
}
finGradetwo.close();//关闭
//boy.showList(gradeOneList);
//boy2.showList(gradeTwoList);
string senmain0[4]={"学生成绩管理系统","1、学生登陆","2、教师登陆","3、退出"};//声明主页面内容
string senexit[3]={"您确定要退出么","(Y)是","(任意健)否"};
do
{
window.mainwin(senmain0,4,4);
cout<<"您的选择是:";
cin>>choose;
switch(choose)
{
case 1:system("cls");Student.Login(window,Student,gradeOneList,gradeTwoList);break;
case 2:system("cls");Ateacher.Login(window,Student,gradeOneList,gradeTwoList,TeacherList);system("pause");break;
case 3:system("cls");
window.questionwin(senexit,3,3);
cin>>choose2;
if(choose2=='Y'||choose2=='y')
{ choose=7;};break;
default:
break;
}
system("cls");
}while(choose!=7);
//存储一年级同学的信息
//存储count1;
ofstream foutGradeOneCount("gradeonestudent\\count.txt",ios::binary);
Count1=gradeOneList.size();
foutGradeOneCount<<Count1;
foutGradeOneCount.close();
//储存学生成绩
ofstream foutGradeone("gradeonestudent\\list1.txt",ios::binary);
for(int i = 0;i<gradeOneList.size();i++)
{
foutGradeone<<gradeOneList[i];
}
foutGradeone.close();
//存储二年级同学的信息
//存储count2;
ofstream foutGradeTwoCount("gradetwostudent\\count.txt",ios::binary);
Count2=gradeTwoList.size();
foutGradeTwoCount<<Count2;
foutGradeTwoCount.close();
//储存学生成绩
ofstream foutGradetwo("gradetwostudent\\list2.txt",ios::binary);
for(int i = 0;i<gradeTwoList.size();i++)
{
foutGradetwo<<gradeTwoList[i];
}
foutGradetwo.close();
system("pause");
}
在主函数进行读取操作,建立一个Browse类,Browse类中包含了大一新生,大二学生,教师的属性,并将他们放在vector容器里,如果某个函数需要使用这些这些数据,就把他传入函数里。
只有在结束程序的时候,才把数据重新存入硬盘,增删改查操作和文件操作是分开的,这样做大大减少了代码量,提高了程序的运算效率。
NO.2—— 删除操作
在图书管理系统中,由于没有使用容器,而且做的是彻底删除,删除操作变得异常复杂,就拿删除一本书库里的书做例子,大致流程是:1、将书单进行备份,得到一份书单-副本,删除原书单的所有数据,对副本进行遍历,如果不是要删除的书就将他放在书单中,如果是要删除的书就忽略,遍历副本后将副本删除。以下是源代码:
void Ruler::deleteBook()//删除、修改图书
{
int i;//计数器
int check=0;//
Bookstorage bo;//图书
string c;//
string c2;//
booklist();//显示书目
int cpbook;//计数器;
ifstream fin("count\\booknumber.txt");//打开记录图书
fin>>cpbook;//
fin.close();//
cout<<"请输入要删除的图书的序号或者书名:";//
cin>>c;//
ifstream fin3("Bookstorage\\booklist.txt");//
ofstream fout4("Bookstorage\\booklist2.txt",ios::app);//
for(i=0;i<cpbook;i++){//
fin3>>bo;//
fout4<<bo;//
}
fin3.close();//
fout4.close();//
ofstream fout5("Bookstorage\\booklist.txt",ios::binary);//
fout5.close();//
ifstream fin2("Bookstorage\\booklist2.txt");//
ofstream fout("Bookstorage\\booklist.txt",ios::app);//
for( i=0;i<cpbook;i++){//
fin2>>bo;//
if(c==bo.getbook()||c==bo.getnumber())//
{
c2.assign(bo.getbook());//
c2=Address2(c2);//
ofstream fout2(c2,ios::binary);//
fout2<<"此书已被下架;";//
fout2.close();//
check=1;//
}//
else
{
fout<<bo;//
}
}
fout.close();//
fin2.close();//
if(check==0)//
{
cout<<"您要删除的书不存在哦"<<endl;//
}//
if(check==1)//
{//
cpbook--;//
ofstream fout3("count\\booknumber.txt",ios::binary);//
fout3<<cpbook;//
fout3.close();//
}
ofstream fout6("bookstorage\\booklist2.txt",ios::binary);//
fout6.close();//
}
这样的方法很复杂,其实,只需要对删除的书做删除标记就可以。
在学生成绩管理系统中就是如此,这种做法不仅更合适(例如:如果删错了方便数据恢复)
总结:
图书管理系统是我做的第一个综合性的C++实验项目,有了编写读书管理系统的经历,学生成绩管理系统很快就编写完成了(只用了三天),之前觉得编写一个图书管理系统好难好难,可是到了最后,还是被一点一点给写出来了,我想,再难走的路,只要踏踏实实一步一步走就肯定会走完,成功最大的敌人就是自卑和半途而废。
当然,这两个系统还只是实验项目。离真正的实践还很远,下一步我想我应该从实践的角度出发,考虑效率和实用性,学习MFC的知识,真正让技术服务于生活。
所以,我下一步要做的就是——班级管理系统。
<!--EndFragment-->
相关推荐
VHDL语言100例 VHDL学习资料VHDL 编程要点VHDL编程心得体会: 100vhdl例子 VHDL 编程要注意问题.doc VHDL——按键消抖.doc VHDL电路简化.doc VHDL编程心得体会.pdf vhd开发的官方手册.pdf 第1例 带控制端口的加法器 ...
【JAVA课程设计报告心得体会——计算器、文本编辑器】 在JAVA课程设计中,我参与了计算器与文本编辑器的开发,这是一次深入理解和实践JAVA编程的宝贵经历。这两个项目不仅涵盖了JAVA的基础语法,还涉及到了面向对象...
在选择和二次开发网站系统时,作者提供了多种CMS(内容管理系统)的比较。例如,帝国CMS功能强大但对新手不太友好,动易的模板系统可能让新手感到困扰,新云适合行业站但对新手来说难度较高,JTBC则因其高度开源和...
c学生成绩管理系统.rar 这次的课程设计和以往写的程序比起来,无论是在篇幅和复杂度上都提高了不少,我在写这个程序的过程中,遇到了不少的困难,也积累了不少的知识和经验,特别是在以前的时候我倍感头疼的文件...
JavaWeb课程设计心得体会 在JavaWeb课程设计过程中,我选择了构建一个在线测试系统,该系统主要服务于学生进行阶段性的自我测试和练习。系统分为练习和测试两个部分,每个部分又包含多个专题。在这个项目中,我主要...
- **背景与意义**:为深入贯彻三届一次职代会精神,提升企业文化的影响力与执行力,通过系统学习《xx文化》手册中的愿景目标、矿山使命、理念精神、行为规范等内容,进一步明确企业发展方向与员工行为准则。...
2021年进行了两次网站改版,旨在简化数据录入和新闻更新的流程,进一步提高了网站的用户体验。 - **关键词与竞价排名管理**:通过监管百度竞价排名系统,定期调整关键词及其出价,以确保在合理的预算范围内获得更多...
最后,每位学生需提交独立运行的应用程序和设计报告,报告应包含需求分析、概要设计、详细设计、测试结果、心得体会等内容,且字数不少于5000字。 通过这样的课程设计,学生能够深入理解面向对象编程的原理,掌握...
此外,还需要编写用户操作手册和其他相关文档,分享设计过程中的心得体会。 考核方式分为理论和实践两部分,理论部分占比30%,主要评估学生对软件工程基本概念、方法和原理的理解;实践部分占比70%,着重考察学生在...
Java实训心得体会 在Java实训的过程中,我们深入了解了Java编程语言的实际应用,这是一次理论与实践相结合的重要体验。实训不仅仅是对已有知识的复习和巩固,更是一个提升技能、拓宽视野和增强团队协作能力的机会。...
3. **可靠性和可用性**:系统出错率不超过2%,且在两个月内出错不超过两次。 4. **数据需求**:用户名仅限字母(大小写)、下划线和数字,不允许特殊字符,并自动过滤输入时的前后空格。 **五、系统设计** 1. **...
### DSP2812 学习心得:深入解析外设模块编程 在深入研究与实践DSP2812的过程中,对外设模块的编程有了更深刻的理解。以下将详细阐述几个关键知识点,包括ADC(模数转换器)的编程、中断控制、定时器配置以及状态...
`printf`和`scanf`这两个常用的输入输出函数,让我能够开始编写能够交互的程序。通过标准输入输出函数,我学会了如何让程序接收用户的输入,并给出相应的输出结果,这一环节对于提高用户体验至关重要。 在理解了...
- **感想和心得体会**:分享个人在项目中的学习体验和成长。 通过这样的课程设计,学生不仅能巩固C语言基础,还能学习到软件工程的实践经验,提高问题解决和团队协作的能力。同时,这也是对C语言功能和面向过程...
《微机原理与接口技术》是一门深度剖析计算机硬件与软件交互的学科,它涵盖了微处理器、内存系统、输入输出接口、总线协议等核心概念。在课程学习中,理解和掌握这些基本概念至关重要,因为它们构成了现代计算机系统...
上篇基本上是第一版的修订,只是做了一个调整,那便是在兼顾 Windows和Linux两方面用户的基础上,默认在Linux下建立开发环境来编写我们的操作系统。至于这样做的原因,在本书第 2章有比较详细的说明。当然,开发环境...
【学生成绩管理系统】是一个常见的教学实践项目,旨在帮助学生理解和掌握软件开发的基本流程,包括模块化设计、问题分析、伪代码编写、流程图绘制以及实际编程。该项目以C语言作为实现工具,通过Microsoft Visual ...
六、实训心得体会 很快的,一个假期又过来了,面对本学期最后一次的校园生活实训,想着刚刚过去的最后一个周,紧张沉默之后更多的是感慨,印在脑海里的每一个足迹都是那么的深,真的说不出是什么感觉,伴着时间,就...