带着学生做课程设计。程序一大,课程中做过了小项目,练过了分解动作,一到合起来了,难免还是要乱了分寸。事实上,实战的功夫,就是这样出来的。(课程设计指导视频链接(第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:数据怎么存不进去的更多相关文章

  1. Facebook存储技术方案:找出“暖性BLOB”数据

    Facebook公司已经在其近线存储体系当中彻底弃用RAID与复制机制,转而采用分布式擦除编码以隔离其所谓的“暖性BLOB”. 暖性?BLOB?这都是些什么东西?大家别急,马上为您讲解: BLOB—— ...

  2. 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 ...

  3. MSSQLSERVER- CharIndex的妙用,找出有妙用

    CharIndex 1:CharIndex语法: CharIndex(expression1,expression2[,start_location]) 2:参数 expression1 一个表达式, ...

  4. 腾讯面试题:10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。

    腾讯面试题:10G 个整数,乱序排列,要求找出中位数.内存限制为 2G. 题目和基本思路都来源网上,本人加以整理. 题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数.内存限制为 2G.只 ...

  5. 找出二进制数中bit为1的最(高/低)索引

    题1.  给定一个无符号整型数据(unsigned int),找出其对应二进制数据中bit位为1的最高/低索引. 比如:对于数据0,返回0:数据1,返回1:数据0x80000000,返回32: 题2. ...

  6. EXCELL中怎么将两列数据对比,找出相同的和不同的数据?

    假设你要从B列中找出A列里没有的数据,那你就在C1单元格里输入“=IF(ISNA(VLOOKUP(B1,A:A,1,0)),"F","T")”显示T就表示有,F ...

  7. python——快速找出两个电子表中数据的差异

    最近刚接触python,找点小任务来练练手,希望自己在实践中不断的锻炼自己解决问题的能力. 公司里会有这样的场景:有一张电子表格的内容由两三个部门或者更多的部门用到,这些员工会在维护这些表格中不定期的 ...

  8. 如何在数据表当中找出被删掉的数据行ID

    这个问题是一年前我刚步入IT行业的一个面试题,当时抓破头皮都想不到的问题,但现在回想过去自身不禁感到可笑,不多扯直接写解决方案.如何在数据表当中找出被删掉的数据行ID,意思是:在一堆的数据当中,让你找 ...

  9. 如何在EXCEL中找出第一列中不包含的第二列数据

    1.找出第一列中不包含的第二列数据:=IFERROR(VLOOKUP(A:A,B:B,1,0),"无") 2.A列相同,B列相加:=SUMIF(G:G,G1,J:J)

随机推荐

  1. [置顶] Hibernate从入门到精通(五)一对一单向关联映射

    上次的博文中Hibernate从入门到精通(四)基本映射我们已经讲解了一下基本映射和相关概念,接下来我们会讲稍微复杂点的映射——关系映射. 关系映射分类 关系映射即在基本映射的基础上处理多个相关对象和 ...

  2. java File的getLastModified在不同操作系统以下存在差异

    java对文件读取改动时间(getLastModified())在不同的操作系统下存在差异  //1.在windows下,返回值是毫秒级别,不存在问题 //2.在Linux下,返回的值是毫秒值,可是会 ...

  3. 2014年百度之星资格赛第二题Disk Schedule

    Problem Description 有非常多从磁盘读取数据的需求,包含顺序读取.随机读取.为了提高效率,须要人为安排磁盘读取. 然而,在现实中,这样的做法非常复杂. 我们考虑一个相对简单的场景. ...

  4. 设置Android设备在睡眠期间始终保持WLAN开启的代码实现

    MainActivity例如以下: package cc.ab; import android.os.Bundle; import android.provider.Settings; import ...

  5. Android 四大组件之 BroadcastReceiver

    0  简介        BroadcastReceiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的 广播.        在Android系统中,广播体现在方方面面,例 ...

  6. Sublime Text 添加到右键菜单 带菜单图标

    1.打开 regedit 2.找到节点 HKEY_CLASSSES_ROOT -> * -> Shell 3.右键选择新建“ 项 ” 这个项的名字将作为右键菜单的菜单名称,我用的“ Sub ...

  7. sql server数据库区分大小写设置

    数据库表中字段alter Table TableName 区分大小写 ALTER Column ColumnName VARCHAR(50) COLLATE Chinese_PRC_CS_AS不区分大 ...

  8. C#抓取网页内容

    学习材料一 <C#抓取网页数据分析> 抓取Web网页数据分析 HttpWebRequest 和 HttpWebResponse 的应用

  9. Oprofile安装与使用探索

    本文分别尝试了oprofile在x86平台和龙芯平台上的安装 一:oprofile的安装与配置(intel+ubuntu12.04) I. Oprofile 安装 Oprofile 包含在 Linux ...

  10. Dubbo使用详解及环境搭建

    一:Dubbo简介 Dubbo是阿里巴巴提供的开源的SOA(面向服务的体系结构)服务化治理的技术框架,据说只是一部分开源的,但一些基本的需求已经可以满足的,而且可扩展性.是一种能取代PHRPC的服务调 ...