带着学生做课程设计。程序一大,课程中做过了小项目,练过了分解动作,一到合起来了,难免还是要乱了分寸。其实,实战的功夫,就是这样出来的。(课程设计指导视频链接(第36课时,3.18 银行系统开发),课程主页在链接,指导文档见链接,示例程序见链接)。
  话说,已经有两位做银行系统的同学和我说,“文件中写不进去数据。程序一退出,明明写进去了,结果却是空文件。”这不是一个小打击。
  做软件,找Bug,有些像打空气,使半天劲,人家就不理你。学计算机的人,练的就是这样的功夫,要学会自己创建线索,找出问题所在。
  话说,出问题的两位同学的程序,框架大体如下:

int main()
{Bank b;   //创建一个银行对象if (pass())    //用pass校验用户{Bank b;b.work();   //完成各种业务}return 0;
}class Bank
{……
}Bank::Bank()
{ifstream infile("account.dat",ios::in);if(!infile){cerr<<"open error!"<<endl;exit(1);}//下面的代码,将之前发生过的业务数据从文件读入银行对象infile.close();
}Bank::~Bank()
{ofstream outfile("account.dat",ios::out);if(!outfile)    //测试文件打开操作是否成功,不成功则提示后退出。{cerr<<"open error!"<<endl;exit(1);}//下面的代码,将银行对象中的业务数据写入文件outfile.close();delete p;
}

  因为数据要在文件里存储,所以,可选的方案是,在构造函数中读文件,在析构函数中写文件。上面的程序就是照这种思路设计的。
  然而,程序退出后,文件就是空的。
  老贺看了也纳闷,写文件的语句中规中矩,然而就是不对。
  仔细审查析构函数中文件的打开方式ios::out,似乎有嫌疑,但排除了。在实际运行的系统中,ios::out的方式不常用,因为这样一打开,也就意味着存在的文件也要重建,用ios::app的更多。
  可是,在这个由大一学生实施的设计中,简化的方案是,将所有的数据读入内存,操作针对内存中的数据,而最后,就是要重建文件,将内存中的全部数据重写一遍。
  几百行的程序,就不可以用眼睛盯着找问题了。单步跟踪,对这样的程序,如果问题具体在哪儿都不清楚,也不是一个好办法。
  析构函数中写文件的部分最可疑。我在析构函数~Bank中加了一句“cout<<"in destructor."<<endl;”。结果发现,最后的,析构函数执行了两次。
  然后,在main函数的return 0;前加了一句“cout<<"end of main"<<endl;”,发现输出的信息是:

in destructor.
end of main
in destructor.

  再看main函数,真相大白了。问题出在main函数中:Bank b出现了两次:一个是属于main函数的局部对象b(前者,第3行),另一个的作用范围,只在if语句的一对花括号内的对象b(后者,第6行)。
 程序初次执行,文件为空,前者执行构造函数,b中保存的是空业务。当用户密码验证成功,会创建后者,自然业务信息也空。当执行完b.work();,会执行后者的析构函数,将这次业务后的业务信息保存在了文件中。文件内容不会是空。
  然而,当程序的执行离开main函数时,其局部的变量b(前者)也要析构,这时就是问题之所在,这个b中的业务信息是空的,文件打开重建后,没有要写入的信息,最后就是空文件了。
  所以,解决的办法,将两个Bank b;,无论前者或后者,去掉一个即可。
  问题解决了,再反思。前述的问题自然不该发生,但这里设计的缺陷也存在。在程序中直接将文件名写定,并且写在构造函数和析构函数中,也就意味着该类的所有对象都用同一个文件(如同Person类中的每个对象都用同一个碗吃饭,多家银行将数据存在一个文件中,太可怕了)。合理的做法是,采取某种机制,不同对象,使用不同的文件。
  当然,对于本文中的问题,就是不该定义两个 Bank b。

找出诡异的Bug:数据怎么存不进去相关推荐

  1. 编写一个汇编语言程序,有一个50个数据的数据区,找出最大数和最小数,分别存放在AX和BX寄存器中

    [微机原理]-汇编题 编写一个汇编语言程序,有一个50个数据的数据区,找出最大数和最小数,分别存放在AX和BX寄存器中. DATA SEGMENT NUM DB 21H,34,23H...DATA E ...

  2. find函数常见错误_如何利用FIND找出你要的数据-EXCEL-开篇3-字符串函数系列-2

    各位好:以后每周都会按学习顺序给大家教EXCEL知识,欢迎关注和学习! 上期作业: 图9 首先我们把这个编成一个数学问题,假如一段字符有汉字和英文组成,如果中英文都算一个字符的话则字数为a,若 汉字为 ...

  3. 找出最接近的数据-MATLAB

    比如要找出一组数A中最接近0.001的数 [~, index]=min(abs(A(:)-0.001)) index是最接近0.001的索引 则最近的值为: Y=A(index):

  4. java 找出list中相同数据_Java获取List中相同的数据

    我现在连废话都懒得说了,直接讲代码吧! int index = 0; for (int i = 0,len = list.size(); i < len; i++) { if(list.size ...

  5. oracle 修改字段长度_Oracle修改字符集前如何找出可能出现问题的数据?

    场景1: 将A库数据迁移到B库,其中A库字符集ZHS16GBK,B库字符集AL32UTF8: 场景2: 修改A库字符集,由ZHS16GBK改成AL32UTF8. 问题: 如何提前知道在以上两个场景下, ...

  6. Excel 中如何找出两列数据中不重复的记录

    现在有两列数据,要在 A 列中找出 B 列中没有的记录,在 B 列中找出 A 列中没有的记录.现在和大家分享一下这个方法. 我们先用一个简单的例子看一下.现在有两列数据,可以是分别在不同的数据单(sh ...

  7. excel表格中添加combobox_Excel中两个表格对比,找出不同数据

    当你有两个Excel工作簿需要对比数据时候,你该怎么做呢?数据少,我们直接用眼睛就可以看到,数据如果太多,那么对比找出不同数据,是一件非常困难的事情.今天,小汪老师就来教大家几招,可以快速有效的帮助大 ...

  8. 别让数据坑了你!用置信学习找出错误标注(附开源实现)

    星标/置顶小屋,带你解锁 最萌最前沿的NLP.搜索与推荐技术 文 | JayLou娄杰(NLP算法工程师,信息抽取方向) 编 |  北大小才女小轶 美 | Sonata 1 前言 在实际工作中,你是否 ...

  9. js分页列表找出最后一页的最后一条数据

    需求场景: 需求描述:如图所示,想要实现列表中排第一位向上的箭头隐藏, 列表中排最后一位向下的箭头隐藏 问题描述: 因为列表存在分页,数据不确定,所以不确定最后一位是否在第几页 代码实现: html: ...

最新文章

  1. 南昌航空航天c语言试卷,2016年南昌航空大学软件学院程序设计复试笔试仿真模拟题...
  2. MySQL运行状态show status详解
  3. python中other_Python other
  4. 5G(7)---5G NR协议栈及功能2 - MAC RLC PDCP SDAP
  5. c语言n个测试用例0为结束,编写测试用例 - osc_4l0h8in9的个人空间 - OSCHINA - 中文开源技术交流社区...
  6. spark on yarn模式:yarn命令杀除当前的application
  7. 2022-2028全球赛车模拟器游戏方向盘行业调研及趋势分析报告
  8. VS2012番茄助手安装破解教程
  9. Ubuntu解决火狐浏览器无法同步书签的问题
  10. 有关费尔防火墙一书TDI代码“网上邻居”不能访问功能的修复
  11. Mysql 启动命令详解
  12. 大数据发展与情报资源整合的关系探索
  13. Liunx操作指令大全(基础知识到应用(易上手),全网最全)
  14. python取excel单元格数值_python读取excel文件单元格中的数据返回类型
  15. Varint+ZigZag编码和解码
  16. 微信公众号及小程序开发入门(二)
  17. 为了会做题而学习股票定价
  18. 2012-11-09《Oopsnbsp;Inbsp;Did…
  19. [生存志] 第67节 夫差信谗杀伍员
  20. HDU 2033 - 人见人爱 A + B

热门文章

  1. URAL 1513. Lemon Tale(简单的递推)
  2. Berkeley DB设计经验
  3. 企业如何制定SOP?
  4. “科幻感”十足,扎克伯格说它将颠覆人类社会
  5. 【硬见小百科】步进电机工作原理及实现方法
  6. 修改网人系统版权信息
  7. playwright实战篇(tx、ali225)
  8. 太实用了!自己动手写软件——我们的密码破解器终于完成了
  9. 双方拍拍肩,双方打屁股
  10. 奥维互动地图浏览器如何添加自定义地图(文章内附地图二维码)