找出诡异的Bug:数据怎么存不进去
带着学生做课程设计。程序一大,课程中做过了小项目,练过了分解动作,一到合起来了,难免还是要乱了分寸。事实上,实战的功夫,就是这样出来的。(课程设计指导视频链接(第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中保存的是空业务。当用户password验证成功。会创建后者。自然业务信息也空。当运行完b.work();,会运行后者的析构函数,将这次业务后的业务信息保存在了文件里。文件内容不会是空。
然而,当程序的运行离开main函数时,其局部的变量b(前者)也要析构,这时就是问题之所在,这个b中的业务信息是空的,文件打开重建后。没有要写入的信息,最后就是空文件了。
所以,解决的办法。将两个Bank b;。不管前者或后者。去掉一个就可以。
问题攻克了,再反思。前述的问题自然不该发生,但这里设计的缺陷也存在。
在程序中直接将文件名称写定。而且写在构造函数和析构函数中,也就意味着该类的全部对象都用同一个文件(如同Person类中的每一个对象都用同一个碗吃饭,多家银行将数据存在一个文件里。太可怕了)。合理的做法是,採取某种机制,不同对象,使用不同的文件。
当然。对于本文中的问题。就是不该定义两个 Bank b。
找出诡异的Bug:数据怎么存不进去的更多相关文章
- Facebook存储技术方案:找出“暖性BLOB”数据
Facebook公司已经在其近线存储体系当中彻底弃用RAID与复制机制,转而采用分布式擦除编码以隔离其所谓的“暖性BLOB”. 暖性?BLOB?这都是些什么东西?大家别急,马上为您讲解: BLOB—— ...
- R语言中如何找出在两个数据框中完全相同的行(How to find common rows between two dataframe in R?)
I would like to make a new data frame which only includes common rows of two separate data.frame. ex ...
- MSSQLSERVER- CharIndex的妙用,找出有妙用
CharIndex 1:CharIndex语法: CharIndex(expression1,expression2[,start_location]) 2:参数 expression1 一个表达式, ...
- 腾讯面试题:10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。
腾讯面试题:10G 个整数,乱序排列,要求找出中位数.内存限制为 2G. 题目和基本思路都来源网上,本人加以整理. 题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数.内存限制为 2G.只 ...
- 找出二进制数中bit为1的最(高/低)索引
题1. 给定一个无符号整型数据(unsigned int),找出其对应二进制数据中bit位为1的最高/低索引. 比如:对于数据0,返回0:数据1,返回1:数据0x80000000,返回32: 题2. ...
- EXCELL中怎么将两列数据对比,找出相同的和不同的数据?
假设你要从B列中找出A列里没有的数据,那你就在C1单元格里输入“=IF(ISNA(VLOOKUP(B1,A:A,1,0)),"F","T")”显示T就表示有,F ...
- python——快速找出两个电子表中数据的差异
最近刚接触python,找点小任务来练练手,希望自己在实践中不断的锻炼自己解决问题的能力. 公司里会有这样的场景:有一张电子表格的内容由两三个部门或者更多的部门用到,这些员工会在维护这些表格中不定期的 ...
- 如何在数据表当中找出被删掉的数据行ID
这个问题是一年前我刚步入IT行业的一个面试题,当时抓破头皮都想不到的问题,但现在回想过去自身不禁感到可笑,不多扯直接写解决方案.如何在数据表当中找出被删掉的数据行ID,意思是:在一堆的数据当中,让你找 ...
- 如何在EXCEL中找出第一列中不包含的第二列数据
1.找出第一列中不包含的第二列数据:=IFERROR(VLOOKUP(A:A,B:B,1,0),"无") 2.A列相同,B列相加:=SUMIF(G:G,G1,J:J)
随机推荐
- Android 代码混淆及第三方jar包不被混淆
为了保护代码被反编译,android引入了混淆代码的概念 1.设置混淆 在工程下找到project.properties文件 在文件中加入proguard.config=${sdk.dir}/tool ...
- oracle 库文件解决的方法 bad ELF interpreter: No such file or directory
今天是2014-05-27,今天遇到一个lib问题,再次记录一下.这是一个案例,更是一种解决该问题的方法过程. 当我们在使用sqlplus 登陆unix数据库的时候,有可能出现类似:xxxxxx ba ...
- Android 4.4 Kitkat Phone工作流程浅析(六)__InCallActivity显示更新流程
本文来自http://blog.csdn.net/yihongyuelan 转载请务必注明出处 本文代码以MTK平台Android 4.4为分析对象,与Google原生AOSP有些许差异,请读者知悉. ...
- ComponentName的意思
ComponentName是用来打开其它应用程序中的Activity或服务的. 使用方法: Intent i=new Intent(); i.setComponent(new ComponentNam ...
- 【贪心】【Uva11729】 Commando War
你有n个部下,每个部下需要完成一项任务.第i个部下需要你花Bi分钟交待任务,然后他会立刻独立地.无间断地执行Ji分钟后完成任务.你需要选择交待任务的顺序,使得所有任务尽早执行完毕(即最后一个执行完的任 ...
- 【温故而知新】Tcp/Ip协议——总览
Tcp/Ip协议 一.概念 “三网”:即电信网络.有线电视网络和计算机网络 标准(Standards) 描述了协议的规定,设定了最简的性能集. 协议(Protocol) 网络设备用于交换信息的系列规则 ...
- 极致精简的fragment实现导航栏切换demo
一个小demo.用button+fragment实现导航栏切换界面,适合刚接触的新手看一下. 效果图 点击第二个后 源码: 主界面 <span style="font-size:18p ...
- sql相关操作
1.两个不同数据库对应字段相应操作 //操作模版:insert into data2.table2(字段1,字段2,字段) select 字段j,字段k,字段m from data1.table1举例 ...
- Eclipse自动生成作者、日期注释等功能设置(转载)
在使用Eclipse 编写Java代码时,自动生成的注释信息都是按照预先设置好的格式生成的. 修改作者.日期注释格式:打开Windows->Preferences->Java->Co ...
- 使用 Camtasia Recorder显示 “ camtasia an error occurred in the recorder: video codec open failed ”
这是因为本机没有codec的缘故,可以下载一个:tscc解码器(TechSmith Screen Capture Codec) 2.0.3.0 安装版 http://www.cngr.cn/dir/2 ...