概述
课程设计报告
一..题目:简易银行管理系统设计
二.设计任务
1.功能:
能够输入和查询客户存款取款记录。在客户文件中,每个客户是一条记录,包括账号、客户姓名、支取密码、客户地址、客户电话、账户总金额;在存取款文件中,每次存取款是一条记录,包括编号、日期、类别、存取数目、经办人。类别分为取款和存款两种。本系统能够输入客户存款或取款记录;根据客户姓名查询存款和取款记录。
2.分步实施:
1、初步完成总体设计,搭好框架,确定人机对话界面,确定函数个数;
2、建立二个文件,输入客户的必要信息,能对文件进行显示、输入、修订、删除等。
3、进一步要求:完成客户姓名查询账号、存款和取款操作,并能得到每个帐户总金额。
4、输出指定账户的交易明细,并按交易日期、交易类别与交易日期联合排序。
5、要求系统运行时加载客户资料,退出时保存(持久化)客户资料;对于交易过程或明细也要求可以做永久保存。
3.要求:
1、用C++语言实现系统;
2、利用结构体数组实现信息的数据结构设计;
3、系统的各个功能模块要求用函数的形式实现;
4、界面友好(良好的人机交互),程序加必要的注释。
二.设计内容
1.数据结构:
本次程序主要是采用数组的方式处理数据,存储时由数组到文本中,读取时由文本到数组,采用c++中对文件流的操作,首先定义了两个全局的结构体数组:
Account Accounts[1000]; //用来存储账户信息
Detail Details[1000]; //用来存储操作信息
程序是采用一位数组的方式进行存储或读取,即第一行的数据表示一个用户的数据,第二行为第二个用户……为了能在创建账户或者操作时,加入数据,定义了两个全局变量:
int AccountCount; //总账户数目
int DetailCount; //总记录数目
在程序刚开始运行指示,随着加载数据的函数将数据的总数赋值给这两个全局变量,在加入信息时,让他们进行自加运算,就可以添加数据了
2.流程图:
如下图所示,程序运行时,首先加载账户信息与操作信息,将数据读取到数组中,然后进
主界面,采用循环语句,在循环中用switch语句来执行6个功能:存款,取款,查询信息,
操作记录,创建账户,退出。完成某一个功能后,再次执行循环语句,也就是回到主菜单。其中
值得注意的是:因为无法直接对文本里面的数据进行修改,必须将数据取出之后,再对数据修改,
再存入,所以请勿直接关闭窗口,否则会造成数据丢失。
然后功能介绍:存款,输入账号即可,就可以进行存款。取款,要输入账号和密码,查询
户信息,输入账号。创建账户,是让新用户自己进行创建,包括账号和密码等。
3.源码分析:
1.首先看头文件:
struct tagAccount//账户信息
{
char no[20];//账号
char name[20];//客户姓名
char password[7];//支取密码
char address[100];//客户地址
char telephone[12];//客户电话
float balance;//账户总金额
};
typedef struct tagAccount Account;
struct tagAccountLink
{
struct tagAccountLink* next;
Account* node;
};
typedef struct tagAccountLink AccountLink;
//enum OperateType {DEPOSIT,WITHDRAW};//存款,取款
struct tagDetail//操作详细信息
{
char no[20];//账号
int year;//交易年份
int month;//月
int day;//日
float amount;//交易金额
//OperateTypeoperation;//存取操作类型
char name[20];//经办人???
};
typedef struct tagDetail Detail;
//操作菜单
int menu();
//加载账户信息
void LoadAccountInformation(char * szFilename);
//加载操作明细
void LoadOperationDetail(char* szFilename);
//保存账户信息
void SaveAccountInformation(char * szFilename);
//保存操作明细
//void SaveOperationDetail(char* szFilename);
//判断函数
int FindAccount(char AccountNo[20]);//判断账户文本账号
int mFindAccount(char mpassword[7]);//确认密码
int nFindAccount(char AccountNo[20]);判断操作列表账户
int sFindAccount(char AccountNo[20]);//创建账户是判断是否有相同账户
头文件包含函数声明,定义两个结构体:账户信息与操作记录。
2.cpp文件的声明部分
#include "Exam4C.h"//包含头文件
#include "time.h" //时间获取
#include <fstream>
#include<string>
#include <stdlib.h>
#include<stdio.h>
#include<windows.h>//Sleep()函数
#include<iostream>
using namespace std;
char szAccountNo[20];//输入账户
char tpassword[7];//确认密码
int AccountCount;//总账户
int DetailCount;//总记录
void Deposit();//存款
void Withdraw();//取款
void Balance();//账户信息
void List();//操作列表
void createAccount();//创建账户
Account Accounts[1000];
Detail Details[1000];
对功能函数的申明,以及要用到的全局变量的申明。
3.main()函数
int main()
{
int nOp;
//读取文件上的账户数据到数组中
LoadAccountInformation("Accounts.dat");
LoadOperationDetail("Operations.dat");
while( nOp = menu() )
{
switch(nOp)
{
case 1:
Deposit();//功能函数,下同
break;
case 2:
Withdraw();
break;
case 3:
Balance();
break;
case 4:
List();
break;
case 5:
createAccount();
break;
}
}
//退出时保存账户信息和交易记录到文件
SaveAccountInformation("Accounts.dat");;//循环结束时保存账户信息
//SaveOperationDetail("Accounts.dat");
return 0;
}
主函数是程序的入口,每一个函数都实现一个功能,其中有一点就是,当用户选择零时,没有写入switch里面,而是直接就结束了循环。
4.以下对几个功能函数进行介绍
(1.)存款函数,取款函数基本一样,就是多了密码判断的内容,这里就不进行举例分析了。
void Deposit()
{
DetailCount++;//总操作数目加1,可以向数组中加入记录
Detail a;//临时成员变量
int nAccountIndex;//获取获取返回值,便于进行判断
float money;
cout<<"请输入存款账号:"<<endl;
scanf("%s",szAccountNo);
//strcpy(a.no,szAccountNo);
if(strlen(szAccountNo)>0)
{
nAccountIndex=FindAccount(szAccountNo);
if(nAccountIndex==-1)
{
printf("nCan't find the account!");
}
else
{
//输入存款数目
cout<<"请输入存款金额"<<endl;
cin>>money;
cout<<"存款成功,正在返回主菜单……";
//修改账户金额
Accounts[nAccountIndex].balance+=money;
a.amount=money;
// cout<<Accounts[nAccountIndex].balance;
struct tm *local;//获取本地时间
time_t t;
t=time(NULL);
local=localtime(&t);
a.year=local->tm_year+1900;
a.month=local->tm_mon+1;
a.day=local->tm_mday;
strcpy(Details[DetailCount].no,szAccountNo);
Details[DetailCount].amount=a.amount;
Details[DetailCount].year=a.year;
Details[DetailCount].month=a.month;
Details[DetailCount].day=a.day;
//增加一条交易记录,操作完成直接存入,但是在账户金额不能这样,因为金额是要进行改动的,记录可以不必修改。
ofstream outfile("Operations.dat",ios::app);
outfile<<Details[DetailCount].no<<"t"<<Details[DetailCount].amount<<"t"<<Details[DetailCount].year<<"t"<<Details[DetailCount].month<<"t"<<Details[DetailCount].day<<endl;
outfile.close();
// DetailCount++;
}
}
else
{
printf("nAccount no is empty!");
}
Sleep(2000);//暂停两秒为了看清提示
system("cls");清屏让操作界面简洁
}
(2)操作列表,账户信息的完成与此类似,这里采用的都是以账号来进行判断,在存储时就把账号存入了里面。不同之处是操作列表没有将账号输出,因为之前你必须得输入账号。
//操作列表
void List()
{
char a[10];//输入字符结束这个函数
int nAccountIndex;
cout<<"请输入您想查询的账号:"<<endl;
cin>>szAccountNo;
if(strlen(szAccountNo)>0)
{
nAccountIndex=nFindAccount(szAccountNo);
if(nAccountIndex==-1)
{
cout<<"没有操作记录!";
}else
{
cout<<"金额"<<"t"<<"日期"<<endl;
for(int i=0;i<DetailCount;i++)
{
if(strcmp(Details[i].no,szAccountNo)==0)
cout<<Details[i].amount<<" "<<Details[i].year<<"-"<<Details[i].month<<"-"<<Details[i].day<<endl;
}
}
}
cout<<"按任意键结束"<<endl;
cin>>a;
system("cls");
}
(3)创建账户,这里采用的是循环语句
//创建账户
void createAccount()
{
int nAccountIndex;
int i=0;//临时变量,为了方便
i=AccountCount+1;//总账户加1,为了能添加数据到数组中
do
{
cout<<"请创建账号:"<<endl;
cin>>Accounts[i].no;
nAccountIndex=sFindAccount(Accounts[i].no);
if(nAccountIndex==-1)//简单判断
{
cout<<"账户存在"<<endl;
}
else{
cout<<"请输入您的姓名:"<<endl;
cin>>Accounts[i].name;
cout<<"请输入您的联系电话:"<<endl;
cin>>Accounts[i].telephone;
cout<<"请输入您的地址:"<<endl;
cin>>Accounts[i].address;
cout<<"请输入密码:"<<endl;
cin>>Accounts[i].password;
cout<<"请确认密码:"<<endl;
cin>>tpassword;
}
} while(strlen(Accounts[i].no)==0||strlen(Accounts[i].password)==0||strcmp(Accounts[i].password,tpassword)!=0);
cout<<"创建成功!!";
cout<<"tt"<<"正在进入,请稍后……"<<endl;
//这个地方也是采取直接存储,但是后面的修改之后,又得清空再存入
ofstream outfile("Accounts.dat",ios::app);
outfile<<Accounts[i].no<<"t"<<Accounts[i].name<<"t"<<Accounts[i].telephone<<"t"<<Accounts[i].address<<"t"<<Accounts[i].password<<"t"<<Accounts[i].balance<<endl;
outfile.close();
AccountCount++;
Sleep(1500);
system("cls");}
(4)加载数据到数组之中,这里以加载账户信息为例分析,加载操作记录与此相同,这不解释了
这个加载是在程序开始时就完成的,为了后面能使用数据。
//加载账户信息
void LoadAccountInformation(char * szFilename)
{
ifstream infile("Accounts.dat",ios::in);
// FILE* fpAccountInfo;
if(infile==NULL)
{
printf("open file failed!n");
}else
{
for(int i=0;1;i++)
{
//这个是用来结束循环的
char temp[20];//临时数组
infile>>temp;//输入数据
if(!temp[0])
break;
strcpy(Accounts[i].no,temp);//相当于赋值
infile>>Accounts[i].name>>Accounts[i].telephone>>Accounts[i].address>>Accounts[i].password>>Accounts[i].balance;
// cout<<Accounts[i].no<<" "<<Accounts[i].name<<" "<<Accounts[i].telephone<<" "<<Accounts[i].password;
}
AccountCount=i;//读取账户总数目
}
infile.close();
}
(5)账户金额修改后的存储。
void SaveAccountInformation(char * szFilename);
{
ifstream infile(szFilename,ios::trunc);
infile.close();
ofstream outfile(szFilename);
for(int i=0;i<AccountCount;i++)//刚才的账户总数在这利用到了
{
outfile<<Accounts[i].no<<"t"<<Accounts[i].name<<"t"<<Accounts[i].telephone<<"t"<<Accounts[i].address<<"t"<<Accounts[i].password<<"t"<<Accounts[i].balance<<endl;
}
outfile.close();
}
4.测试信息
5.主要问题及解决方案
(1)文件读取出来时,刚开始后面空的数据也读出来:
通过if语句判断为空时,结束循环,前面有提到的。
(2)操作完成后,执行太快,无法看清提示:
用了暂停语句Sleep()函数,在加入头文件#include<windows.h>。
(3)存储时会将数据覆盖:
存储时在里面加入ios::app,直接加入文件末尾。
(4)一个功能完成时,会出现重复个界面:
用system("cls");把内容清除,再进入界面。
(5)无法直接修改账户的总金额:
先读取到数组中。然后把文本里的数据清空后,再存入数据,就可以修改了。
(6)如何能读取到某个人的操作记录:
将操作记录里也存入账号,用账号加以判断。
(7)如何读取某个人多次的操作记录:
利用循环语句,将相同账号的内容全部读取出来。
(8)如何在创建之后能继续进行存款,取款操作:
直接在存数据的数据中加入信息,然后读取数组里的内容。
(9)存数据时怎么样才能减少循环次序:
定义全局变量,在读入时获取总账户数,存入时就利用它。
(10)如何获取时间:
利用头文件time.h,利用里面的函数和结构体。
6.总节
通过此次的课程设计,让我学到了很多东西,比如对文件的操作,函数的调用,这个设计用到了c++面向过程编程的很多东西。从其他的方面来看,着考验了我们是否细心与逻辑思维是否严密,总程序的整体框架,到每个功能的实现,都需要我们细心的思考。还有就是交流的重要性,当我们遇到问题时,实在无法解决时候,就要与别人进行讨论,或许能够打开我们的思维。这次的课程总的来说让我获益匪浅,尽管也遇到了很多难题,不过最终还是解决,这就让人值得欣慰。不实际的行动是无法提高自己,多加练习,多加思考,就能解决很多问题。
指导老师意见:
成绩: 教师签名:
年 月 日
最后
以上就是奋斗冬日为你收集整理的课程设计报告,简单的银行管理系统的全部内容,希望文章能够帮你解决课程设计报告,简单的银行管理系统所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复