好长时间没有写同步项目了,很着急,很自责。原因有两点:(1)深入做下去,需要用到字符串、数组、结构体、文件等等,单独地用其中一个,有些地方显得有些太迁就;(2)近日学的一些内容也有大量的练习可做,不像刚开始,急需要一些看似“实用”的项目给大家提神。
再次决心将这个任务写下去,就将任务一下子说透吧。最近大家的进步已经能够接受我的这种“和盘托出”了。从技术角度,有了函数,写程序变成一种可组合的事情,不具备条件的内容可以先放一放,有时间就一点儿一点儿往前做。偶尔一些在部分任务上“卡”住了,也不致于整个项目无法进行下去。只要习惯了“模块化”的方法,这种做法还是可以行得通的。
项目的总体目标
开发一个接近于目前银行柜台上存取款业务的程序,工作流程和业务要求尽可能一致。具体包括:
(1)创建新的账户
(2)账户登录
(3)存款
(4)取款
(5)修改密码
(6)查询
(7)转账
(8)银行的一些后台服务
数据存储与表示问题
1、账户
银行支持众多的客户,每名客户可以开多个活期存款和定期存款的账户。所以,以账户为标志进行操作,而不是以客户为标志。账户信息包括:开户账号、储户的身份证号码、真实姓名、通信地址和电话号码、账户类型(活期、银行卡、定期——3月、半年、1年、3年、5年,按现有银行的规定的设,可以在以后加上信用卡业务,可以透支,需要调研相关业务)、开户时间、年利率、存款余额、账户密码;
数据的保存需要用一个单独的文件,将这些信息保存下来。可以采取的方案包括:(1)用ASCII文件存储,各部分数据间用空格隔开;(2)自学二进制文件,这样可以避免一次必须将所有账户信息都读入到内存中去,可以实现对账户信息的“随机”存取;(3)用数据库技术,这是后话,学C++期间玩好文件更见功夫。
下面的讨论都以用ASCII文件存储的方式,有不少缺点,但简单、直观一些,用我们在实验课中尝试过的方法就能操作。
在程序开始运行时,需要将文件中的信息读入到内存中(用结构体数组,见后面的说明),在程序退出前,应该将内存中的数据保存到文件中。为后面讨论方便,保存账户信息的文件名为account.txt。
在实际的系统中,文件可能还得考虑安全性等因素,可以在将信息存入文件中时采取点“加密”的手段,各种练习题中有这方面的建议。
在内存中,所有账户保存在一个结构体数组中,一个账户是一个数组元素,对应的一个结构体。最简单的处理是
为了便于查询,在accounts数组中的数据最好按照账户号有序。更高级的做法是,专门设置索引,可以按各种可能查询的关键字有序,相关技术暂且不表。
用数组需要点用太多的空间,不是一个最佳的办法。还可以考虑用动态链表存储,省了空间,但在时间效率上打了折扣。还有好的办法,也留待以后解决。
如果想将活期、定期、银行卡、信用卡的账号信息分别存储,请自行确定方案。
2、业务记录
已经完成的业务,需要记录下来,同样需要永久保存在文件中。内容包括账号信息中的所有项目,再加上业务内容(存/取/查等)、金额、时间等。如果账户上的余额为0,就可以将account.txt中的相关记录删除(程序结束时,将余额为0的accounts数组中的结构体不再保存即可)。保存业务记录的文件名定为log.txt。
在程序中,需要定义结构体数组,记录发生的业务。
程序开始运行后,每发生一笔业务,都应在operations中增加一条记录。log.txt中都是以前的业务数据,无须读入,但每一次程序结束之前都应该将operations中的数据增加到log.txt中去。
在实际的系统中,多个文件中存储的数据不能有这么多的重复,除了效率上的考虑,这是会出乱子的。但是在我们的这个系统中,先这样处理。
3、存款利率等
存款利率也可以通过文件存储,以适应金融动荡中不断的调息,免得政策变一次就得修改一次程序。请自行设计方案完成。存款利率按最新公布的数据执行,上网自己查找。
也可以在程序中定义全局的常变量表示利率,作为一种最简单的实现方法。
业务及流程
1、创建新的账户
输入新开账户的有关信息,记录到数组accounts中,ACC_COUNT增加1。如果accounts中数据按账号有序,需要采取措施使其保持顺序。输入密码时需要重复输入。还可以想办法输入的密码在屏幕上不可见。
开户的同时,实际已经增加了一笔存款。
2、账户登录
其余的所有操作必须在账户登录以后才能进行。
账户和密码要用字符串或字符数组类型。尽管可能是由数字构成的,我们只关注其符号,而不是要用来做什么计算。想一下,现在各种系统中,你的密码可以是以0打头的,有的还限制位数,这都是使用字符串处理这些问题的佐证。
登录过程:输入账号、密码,如果正确,出现做后续操作的界面,否则提示重输。三次不正确,则不能再试。
活期和银行卡已的账户的存款,在accounts修改余额,在operations中增加一条存款记录。
程序结束时,这些内容将会被存储到文件中。
活期和银行卡新开户的存款及定期存款,其功能在创建新账户中已经实现。
4、取款
活期和银行卡账户只要余额就能取款,取款额不得超过余额,取款成功后,在屏幕上输出有关信息,在accounts中修改余额,在operations中增加一条取款记录。如果活期存款要将余额全部取走,利息计算采用累积计息(参见8、银行的一些后台服务),对数据的存储参见定期一次性取款的做法。
定期存款用户可以在到期日一次性全部支取,取款成功后,在屏幕上输出包括利息在内的有关信息,在accounts中修改余额,在operations中增加一条取款记录(注意记利息)。
对定期存款用户,还支持部分提前支取。银行规定,定期存款的提前支取可分为部分和全额支取两种。您可根据自己的实际需要,办理部分提前支取,这样剩下的存款仍可按原有存单存款日、原利率、原到期日计算利息。提前支取的部分按活期计算利息,连同利息付给用户,对数据存储的修改的要求参照上述内容进行。
程序结束时,相关的数据将会被存储到文件中。注意,accounts中余额为0的账户将不再写入相应的文件中,相当于删除。
5、修改密码
输入旧密码正确的前提下,两次输入的新密码相同,则修改accounts中的信息。
程序结束时将数据存入文件,新密码也随之保存下来。
6、查询
储户在成功登录某一账户后,可以查询本账号的余额(直接显示accounts中信息即可);对定期储户的服务,还可以查看该账户的到期日期。
下面的功能可能商业银行都不一定支持,我们可以做一些:
(1)以登录后账户户主的身份证号为根据,查看其名下的所有账户信息;
(2)查看某账户下的所有业务发生情况:以前存、取、查等的情况。这一功能需要直接访问log.txt完成。
(3)从银行角度,可以查询统计某一段时期内的业务量(存款额、取款额、利息支出或更细致、专业的信息,要有贷款业务就更多了)等信息。就你能想到的试着去实现吧。要知道,计算机系统中查询、统计功能应该是要做好的。
7、转账
转账只在活期和银行卡账号间进行,定期不允许。输入另一个账户的账号和开户人姓名,将一定的金额由当前账户减去,加到指定账户上去。注意另一账户必须存在,当前账户的金额足够。在accounts中两个账户的余额都要修改(一增一减),一次转账在operations中要增加两条记录(一入一出)。
8、银行的一些后台服务
这部分功能通过输入特殊密码,或者菜单中给安排特殊途径进入。
银行会在每年6月30日和12月30日给所有活期和银行卡用户计算利息,方法是分段累积计算,即1月20日到2月23日间余额为200元,按200元33天计息,当天存款100元,15后后又取款,则再加300元15天的利息。这个计算需要针对account.txt每一个活期和银行卡账户,在log.txt中按时间找到业务记录进行计算。完成后,利自己按存款的办法存入到账号中去。
定期存款默认都选择到期约定转存。对account.txt每一个定期账户,如果当天到期,自动办理取款手续,并且连本带息再办理存入(账号不变)。log.txt中需要记录两笔。
程序结构及实施策略
采用模块化的设计思想,各个功能分别用函数实现。更具体的功能,采用函数的嵌套调用完成,以简化每个代码段的实现。函数的功能应该尽可能的单一和抽象,这是提高设计质量的保证。
建立多文件的工程实现项目。每个文件中的函数数目不要超过10个,且功能相对集中一些。例如,所有涉及取款的函数放在一个文件中。请将整个工程保存下来,每次哪怕只修改一个函数,也是针对整个工程的修改。
建议将当前登录的账户号、accounts和operations定义为全局变量,则可以不必通过参数传递共享数据。这在目前的需求下还是合适的选择。
在实施中,不可以只将“做出来”作为目标。作为学习,可以做几个版本,例如账户信息的存储,可以用数组做一遍,用动态链表做一遍,在做的中间,你还可以发现这些方法各自的优点和缺陷,思考用其他方法再做。再比如,可以选择用ASCII文件,也可以使用二进制文件存储数据。类似这种基础数据结构的改变,可能影响整个程序。同一任务,不同方法,可以让你有更多的机会去比较、体会,获得将来在专业课学习中非常珍贵的提前体验。这些,在当今的大学学习中异常缺乏和宝贵。
结束语
目前给出了适合做的事情和建议,题目已经不小,但依靠本学期所学内容就可以完成。其中的解决方案可能并不是最优的,同学们可以先照着建议做,当然,也会找出更好的方法。
本题目没有考虑利息税,没有考虑信用卡,没有支持网上银行的消费,没有支持外币。这都是可能拓展的需求。有时间可以上网找材料了解一下这些业务,自己扩充。
还有可能的工作是,做成窗口版的系统。不用追求太花的界面,用一个对话框,实现功能即可。
临近期末,需要将主要精力放在围绕课堂内容,多练习和复习。这个项目可以作为漫长的寒假中的点心去吃,我们的寒假达六周之久。也希望有更多的同学能在下学期之前完成该项目的全部或部分。
到下学期,学习了面向对象技术之后,用全新的视角重新考察和设计这个系统,还将有另外一番气象。
再次决心将这个任务写下去,就将任务一下子说透吧。最近大家的进步已经能够接受我的这种“和盘托出”了。从技术角度,有了函数,写程序变成一种可组合的事情,不具备条件的内容可以先放一放,有时间就一点儿一点儿往前做。偶尔一些在部分任务上“卡”住了,也不致于整个项目无法进行下去。只要习惯了“模块化”的方法,这种做法还是可以行得通的。
项目的总体目标
开发一个接近于目前银行柜台上存取款业务的程序,工作流程和业务要求尽可能一致。具体包括:
(1)创建新的账户
(2)账户登录
(3)存款
(4)取款
(5)修改密码
(6)查询
(7)转账
(8)银行的一些后台服务
数据存储与表示问题
1、账户
银行支持众多的客户,每名客户可以开多个活期存款和定期存款的账户。所以,以账户为标志进行操作,而不是以客户为标志。账户信息包括:开户账号、储户的身份证号码、真实姓名、通信地址和电话号码、账户类型(活期、银行卡、定期——3月、半年、1年、3年、5年,按现有银行的规定的设,可以在以后加上信用卡业务,可以透支,需要调研相关业务)、开户时间、年利率、存款余额、账户密码;
数据的保存需要用一个单独的文件,将这些信息保存下来。可以采取的方案包括:(1)用ASCII文件存储,各部分数据间用空格隔开;(2)自学二进制文件,这样可以避免一次必须将所有账户信息都读入到内存中去,可以实现对账户信息的“随机”存取;(3)用数据库技术,这是后话,学C++期间玩好文件更见功夫。
下面的讨论都以用ASCII文件存储的方式,有不少缺点,但简单、直观一些,用我们在实验课中尝试过的方法就能操作。
在程序开始运行时,需要将文件中的信息读入到内存中(用结构体数组,见后面的说明),在程序退出前,应该将内存中的数据保存到文件中。为后面讨论方便,保存账户信息的文件名为account.txt。
在实际的系统中,文件可能还得考虑安全性等因素,可以在将信息存入文件中时采取点“加密”的手段,各种练习题中有这方面的建议。
在内存中,所有账户保存在一个结构体数组中,一个账户是一个数组元素,对应的一个结构体。最简单的处理是
structAccount { char acc_num[18];//开户账号 char ID_card[18];//身份证号,尽管全由数字字符构成,定义成字符串是合适的 char name[12];//储户姓名 …… } Account accounts[5000];//先设一个“足够大”的数组 int ACC_COUNT;//在ACC_COUNT中,存放实际的账户个数
为了便于查询,在accounts数组中的数据最好按照账户号有序。更高级的做法是,专门设置索引,可以按各种可能查询的关键字有序,相关技术暂且不表。
用数组需要点用太多的空间,不是一个最佳的办法。还可以考虑用动态链表存储,省了空间,但在时间效率上打了折扣。还有好的办法,也留待以后解决。
如果想将活期、定期、银行卡、信用卡的账号信息分别存储,请自行确定方案。
2、业务记录
已经完成的业务,需要记录下来,同样需要永久保存在文件中。内容包括账号信息中的所有项目,再加上业务内容(存/取/查等)、金额、时间等。如果账户上的余额为0,就可以将account.txt中的相关记录删除(程序结束时,将余额为0的accounts数组中的结构体不再保存即可)。保存业务记录的文件名定为log.txt。
在程序中,需要定义结构体数组,记录发生的业务。
struct Operation { char acc_num[18];//开户账号 char ID_card[18];//身份证号,尽管全由数字字符构成,定义成字符串是合适的 char name[12];//储户姓名 …… char op_type;//业务内容(a-存/b-取/c-查等) float money;//金额 float interest;//如果取款,记下银行支出的利息 char time[10];//时间,可以查C++中时间表示,也可形如yyyy-mm-dd-hh:mm:ss } Operation operations[2000];//先设一个“足够大”的数组 int op_count;//实际发生的业务数目
程序开始运行后,每发生一笔业务,都应在operations中增加一条记录。log.txt中都是以前的业务数据,无须读入,但每一次程序结束之前都应该将operations中的数据增加到log.txt中去。
在实际的系统中,多个文件中存储的数据不能有这么多的重复,除了效率上的考虑,这是会出乱子的。但是在我们的这个系统中,先这样处理。
3、存款利率等
存款利率也可以通过文件存储,以适应金融动荡中不断的调息,免得政策变一次就得修改一次程序。请自行设计方案完成。存款利率按最新公布的数据执行,上网自己查找。
也可以在程序中定义全局的常变量表示利率,作为一种最简单的实现方法。
业务及流程
1、创建新的账户
输入新开账户的有关信息,记录到数组accounts中,ACC_COUNT增加1。如果accounts中数据按账号有序,需要采取措施使其保持顺序。输入密码时需要重复输入。还可以想办法输入的密码在屏幕上不可见。
开户的同时,实际已经增加了一笔存款。
2、账户登录
其余的所有操作必须在账户登录以后才能进行。
账户和密码要用字符串或字符数组类型。尽管可能是由数字构成的,我们只关注其符号,而不是要用来做什么计算。想一下,现在各种系统中,你的密码可以是以0打头的,有的还限制位数,这都是使用字符串处理这些问题的佐证。
登录过程:输入账号、密码,如果正确,出现做后续操作的界面,否则提示重输。三次不正确,则不能再试。
三次不正确,还可以冻结账户。你可以在调研基础上,给我们的这个项目加一个解冻账户的功能。
活期和银行卡已的账户的存款,在accounts修改余额,在operations中增加一条存款记录。
程序结束时,这些内容将会被存储到文件中。
活期和银行卡新开户的存款及定期存款,其功能在创建新账户中已经实现。
4、取款
活期和银行卡账户只要余额就能取款,取款额不得超过余额,取款成功后,在屏幕上输出有关信息,在accounts中修改余额,在operations中增加一条取款记录。如果活期存款要将余额全部取走,利息计算采用累积计息(参见8、银行的一些后台服务),对数据的存储参见定期一次性取款的做法。
定期存款用户可以在到期日一次性全部支取,取款成功后,在屏幕上输出包括利息在内的有关信息,在accounts中修改余额,在operations中增加一条取款记录(注意记利息)。
对定期存款用户,还支持部分提前支取。银行规定,定期存款的提前支取可分为部分和全额支取两种。您可根据自己的实际需要,办理部分提前支取,这样剩下的存款仍可按原有存单存款日、原利率、原到期日计算利息。提前支取的部分按活期计算利息,连同利息付给用户,对数据存储的修改的要求参照上述内容进行。
程序结束时,相关的数据将会被存储到文件中。注意,accounts中余额为0的账户将不再写入相应的文件中,相当于删除。
5、修改密码
输入旧密码正确的前提下,两次输入的新密码相同,则修改accounts中的信息。
程序结束时将数据存入文件,新密码也随之保存下来。
6、查询
储户在成功登录某一账户后,可以查询本账号的余额(直接显示accounts中信息即可);对定期储户的服务,还可以查看该账户的到期日期。
下面的功能可能商业银行都不一定支持,我们可以做一些:
(1)以登录后账户户主的身份证号为根据,查看其名下的所有账户信息;
(2)查看某账户下的所有业务发生情况:以前存、取、查等的情况。这一功能需要直接访问log.txt完成。
(3)从银行角度,可以查询统计某一段时期内的业务量(存款额、取款额、利息支出或更细致、专业的信息,要有贷款业务就更多了)等信息。就你能想到的试着去实现吧。要知道,计算机系统中查询、统计功能应该是要做好的。
7、转账
转账只在活期和银行卡账号间进行,定期不允许。输入另一个账户的账号和开户人姓名,将一定的金额由当前账户减去,加到指定账户上去。注意另一账户必须存在,当前账户的金额足够。在accounts中两个账户的余额都要修改(一增一减),一次转账在operations中要增加两条记录(一入一出)。
8、银行的一些后台服务
这部分功能通过输入特殊密码,或者菜单中给安排特殊途径进入。
银行会在每年6月30日和12月30日给所有活期和银行卡用户计算利息,方法是分段累积计算,即1月20日到2月23日间余额为200元,按200元33天计息,当天存款100元,15后后又取款,则再加300元15天的利息。这个计算需要针对account.txt每一个活期和银行卡账户,在log.txt中按时间找到业务记录进行计算。完成后,利自己按存款的办法存入到账号中去。
定期存款默认都选择到期约定转存。对account.txt每一个定期账户,如果当天到期,自动办理取款手续,并且连本带息再办理存入(账号不变)。log.txt中需要记录两笔。
程序结构及实施策略
采用模块化的设计思想,各个功能分别用函数实现。更具体的功能,采用函数的嵌套调用完成,以简化每个代码段的实现。函数的功能应该尽可能的单一和抽象,这是提高设计质量的保证。
建立多文件的工程实现项目。每个文件中的函数数目不要超过10个,且功能相对集中一些。例如,所有涉及取款的函数放在一个文件中。请将整个工程保存下来,每次哪怕只修改一个函数,也是针对整个工程的修改。
建议将当前登录的账户号、accounts和operations定义为全局变量,则可以不必通过参数传递共享数据。这在目前的需求下还是合适的选择。
在实施中,不可以只将“做出来”作为目标。作为学习,可以做几个版本,例如账户信息的存储,可以用数组做一遍,用动态链表做一遍,在做的中间,你还可以发现这些方法各自的优点和缺陷,思考用其他方法再做。再比如,可以选择用ASCII文件,也可以使用二进制文件存储数据。类似这种基础数据结构的改变,可能影响整个程序。同一任务,不同方法,可以让你有更多的机会去比较、体会,获得将来在专业课学习中非常珍贵的提前体验。这些,在当今的大学学习中异常缺乏和宝贵。
结束语
目前给出了适合做的事情和建议,题目已经不小,但依靠本学期所学内容就可以完成。其中的解决方案可能并不是最优的,同学们可以先照着建议做,当然,也会找出更好的方法。
本题目没有考虑利息税,没有考虑信用卡,没有支持网上银行的消费,没有支持外币。这都是可能拓展的需求。有时间可以上网找材料了解一下这些业务,自己扩充。
还有可能的工作是,做成窗口版的系统。不用追求太花的界面,用一个对话框,实现功能即可。
临近期末,需要将主要精力放在围绕课堂内容,多练习和复习。这个项目可以作为漫长的寒假中的点心去吃,我们的寒假达六周之久。也希望有更多的同学能在下学期之前完成该项目的全部或部分。
到下学期,学习了面向对象技术之后,用全新的视角重新考察和设计这个系统,还将有另外一番气象。