<2015年大一C++实训项目>银行储蓄系统
来源:互联网 发布:linux桌面使用入门 编辑:程序博客网 时间:2024/05/16 11:39
/******************************************** 版权所有 (C)2015,Annpion。** 文件名称:main.cpp*文件标识:无*内容摘要:该代码是程序的主要运行的首部分。*其他说明:无*当前版本:V1.0*作者:王耀鹏*完成日期:2015/7/17*******************************************/#include <iostream>#include "Bank.h"using namespace std;int main(){ cout<<"+-----------------------+\n"; cout<<"+ 欢迎光临中国银行 +\n"; cout<<"+-----------------------+\n"; if (pass()) { Bank b; b.work(); } return 0;}/******************************************** 版权所有 (C)2015,Annpion。** 文件名称:Bank.h*文件标识:无*内容摘要:该代码定义、声明类以及函数。*其他说明:无*当前版本:V1.0*作者:王耀鹏*完成日期:2015/7/17*******************************************/#ifndef BANK_H_INCLUDED#define BANK_H_INCLUDED#include <cstring>using namespace std;struct UserIndex{ int No; long offset;};class Bank;class User{public: void setUser(int acc, char *nam, int pw, double bal,int sta); void showName(); void showStatus(string prompt); int getaccount(); void showBalance(string prompt); //显示余额,前面加上提示词prompt bool passwordIsRight(); //校验密码,输入的密码正确则返回true bool isNormalUser(); //存款、取款、转帐等功能,需要账户处于正常姿态,处于正常状态时返回true,其他情形返回false并提示 friend class Bank;private: int account; char name[8]; int password; double balance; int status;};class Bank{public: Bank(); ~Bank(); void work(); void openAccount(); void cancelAccount(); void save(); void withdraw(); void showAccount(); void transferAccounts(); void reportLoss(); void cancelLoss(); void updatePassword(); void createIndex(); void EnlargeArray(); void writeIndex(UserIndex *ui, int n); long getUser();private: int maxNum; int UserNum; UserIndex *userIndex;};int pass();int chooseInMenu();int inputPassword();void createIndex();void writeIndex(UserIndex *ui, int n);void init();void done();void EnlargeArray();#endif // BANK_H_INCLUDED/******************************************** 版权所有 (C)2015,Annpion。** 文件名称:Bank.cpp*文件标识:无*内容摘要:该代码实现Bank类中的各个函数。*其他说明:无*当前版本:V1.0*作者:王耀鹏*完成日期:2015/7/17*******************************************/#include <iostream>#include <fstream>#include <cstdlib>#include <algorithm>#include <ctype.h>#include "bank.h"using namespace std;fstream dataFile, indexFile;/********************************************功能描述:构造Bank类中的数据成员。*输入参数:User-用户类*输出参数:userIndex-用户索引 UserNum-用户人数*返回值:无*其他说明:从文件中读入用户数据作成用户索引。*******************************************/Bank::Bank(){ createIndex();}/********************************************功能描述:析构Bank类。*输入参数:无*输出参数:无*返回值:无*其他说明:把索引写入文件,清除内存。*******************************************/Bank::~Bank(){ writeIndex(userIndex,UserNum); dataFile.close(); delete []userIndex;}/********************************************功能描述:选择所需的功能。*输入参数:iChoice-功能序号*输出参数:无*返回值:无*其他说明:利用输入的序号调用各个功能函数。*******************************************/void Bank::work(){ int iChoice; do { iChoice = chooseInMenu(); switch(iChoice) { case 1: openAccount(); //开户 break; case 2: cancelAccount(); //注销账户 break; case 3: save(); //存款 break; case 4: withdraw(); //取款 break; case 5: showAccount(); //查询余额 break; case 6: transferAccounts(); //转账 break; case 7: reportLoss(); //挂失 break; case 8: cancelLoss(); //解除挂失 break; case 9: updatePassword(); //更改密码 break; case 0: cout<<"欢迎您再来. "<<endl; } } while(iChoice);}/********************************************功能描述:开户。*输入参数:user-用户类*输出参数:userIndex-用户索引 UserNum-用户人数*返回值:无*其他说明:用户增加,索引增加,人数增加。*******************************************/void Bank::openAccount(){ User user; int acc; //账号 char nam[8]; //姓名 int pw; //密码 double bal; //金额 int sta; cout<<"正在开户"<<endl; acc=10001+UserNum; cout<<"账号:"<<acc<<endl; cout<<"户主姓名:"; cin>>nam; int iPass1, iPass2; cout<<"密码:"; iPass1=inputPassword(); //输入密码1 cout<<"确认密码:"; iPass2=inputPassword(); //输入密码2 if(iPass1==iPass2) { pw=iPass1; sta=0; //账户状态为“正常” cout<<"存入金额:"; cin>>bal; user.setUser(acc, nam, pw, bal,sta); dataFile.seekp(0,ios::end); dataFile.write((char *)&user,sizeof(user)); dataFile.seekg(-sizeof(User),ios::end); userIndex[UserNum].No=user.account; userIndex[UserNum].offset=dataFile.tellg(); UserNum++; //正式用户数增加1,确认了新用户已经加入 cout<<"成功开户!"<<endl; dataFile.seekp(0,ios::beg); dataFile.write((char *)&UserNum,sizeof(UserNum)); if(UserNum>=maxNum) EnlargeArray(); } else { cout<<"两次密码不一致,未成功开户!"<<endl; //没有N++,则读入的值无效 }}/********************************************功能描述:销户。*输入参数:location-用户数据位置*输出参数:user-用户类*返回值:无*其他说明:用户状态被改变。*******************************************/void Bank::cancelAccount(){ User user; long location; location = getUser(); //根据账号查询用户,返回用户的偏移量 if(location>=0) //说明id账户存在 { dataFile.seekg(location); dataFile.read((char *)&user,sizeof(user)); user.showName(); if(user.isNormalUser()) { if(user.passwordIsRight()) { user.showBalance("余额"); //提示"余额"二字,显示金额 cout<<"确认销户(y/n)?"; if(tolower(getchar())=='y') { user.showBalance("销户成功!本次取款金额为"); user.balance=0; //取款后余额变0 user.status=2; //状态变为注销 dataFile.seekp(location); dataFile.write((char *)&user,sizeof(user)); } else { cout<<"你取消了操作,销户失败!"<<endl; } fflush(stdin); //清除了getchar()时在键盘缓存中的遗留,以免影响后续操作 } } }}/********************************************功能描述:存款。*输入参数:location-用户数据位置*输出参数:user-用户类*返回值:无*其他说明:用户余额改变。*******************************************/void Bank::save(){ User user; long location; double money; location = getUser(); //根据账号查询用户,返回用户的偏移量 if(location>=0) //说明id账户存在 { dataFile.seekg(location); dataFile.read((char *)&user,sizeof(user)); user.showName(); if(user.isNormalUser()) { cout<<"输入存款额:"; cin>>money; user.balance+=money; user.showBalance("存款后,您有"); dataFile.seekp(location); dataFile.write((char *)&user,sizeof(User)); } } return;}/********************************************功能描述:取款。*输入参数:location-用户数据位置*输出参数:user-用户类*返回值:无*其他说明:用户余额改变。*******************************************/void Bank::withdraw(){ User user; long location; double money; location = getUser(); //根据账号查询用户,返回用户的偏移量 if(location>=0) //说明id账户存在 { dataFile.seekg(location); dataFile.read((char *)&user,sizeof(User)); user.showName(); if(user.passwordIsRight()) { if(user.isNormalUser()) { cout<<"输入取款额:"; cin>>money; if(money>user.balance) //亲,不玩透支 { cout<<"余额不足,取款失败!"<<endl; } else { user.balance-=money; user.showBalance("取款后,还有"); dataFile.seekp(location); dataFile.write((char *)&user,sizeof(User)); } } } } return;}/********************************************功能描述:查询。*输入参数:location-用户数据位置*输出参数:user-用户类*返回值:无*其他说明:显示用户数据。*******************************************/void Bank::showAccount(){ User user; long location; location = getUser(); //根据账号查询用户,返回用户的偏移量 if(location>=0) //说明id账户存在 { dataFile.seekg(location); dataFile.read((char *)&user,sizeof(user)); user.showName(); if(user.passwordIsRight()) { user.showBalance("余额:"); user.showStatus("状态:"); } } return;}/********************************************功能描述:转账。*输入参数:location-用户数据位置*输出参数:user-用户类*返回值:无*其他说明:用户余额被改变。*******************************************/void Bank::transferAccounts(){ User user1,user2; long whoout, whoin; double money; cout<<"转出自"; whoout = getUser(); //根据账号查询用户,返回用户的偏移量 if(whoout>=0) //说明id账户存在 { dataFile.seekg(whoout); dataFile.read((char *)&user1,sizeof(User)); user1.showName(); if(user1.isNormalUser()) { if(user1.passwordIsRight()) { cout<<"输入转账金额:"; cin>>money; if(money>user1.balance) { cout<<"余额不足,转账失败!"<<endl; } else { cout<<"转出到"; whoin = getUser(); //根据账号查询用户,返回用户的偏移量 if(whoin>=0) //说明id账户存在 { dataFile.seekg(whoin); dataFile.read((char *)&user2,sizeof(User)); if(user2.isNormalUser()) { user1.balance-=money; user2.balance+=money; user1.showBalance("转账后,您还有"); dataFile.seekp(whoout); dataFile.write((char *)&user1,sizeof(User)); dataFile.seekp(whoin); dataFile.write((char *)&user2,sizeof(User)); } } } } } } return;}/********************************************功能描述:挂失。*输入参数:location-用户数据位置*输出参数:user-用户类*返回值:无*其他说明:用户状态被改变。*******************************************/void Bank::reportLoss(){ User user; long location; location = getUser(); //根据账号查询用户,返回用户的偏移量 if(location>=0) //说明id账户存在 { dataFile.seekg(location); dataFile.read((char *)&user,sizeof(User)); user.showName(); if(user.passwordIsRight()) { if(user.isNormalUser()) { user.status=1; cout<<"挂失成功"<<endl; dataFile.seekp(location); dataFile.write((char *)&user,sizeof(user)); } } } return;}/********************************************功能描述:解挂。*输入参数:location-用户数据位置*输出参数:user-用户类*返回值:无*其他说明:用户状态被改变。*******************************************/void Bank::cancelLoss(){ User user; long location; location = getUser(); //根据账号查询用户,返回用户的偏移量 if(location>=0) //说明id账户存在 { dataFile.seekg(location); dataFile.read((char *)&user,sizeof(User)); user.showName(); if(user.passwordIsRight()) { if(user.status==0) { cout<<"该账户处于正常状态,不需要解除挂失"<<endl; } else if(user.status==1) { user.status=0; cout<<"解除挂失成功"<<endl; dataFile.seekp(location); dataFile.write((char *)&user,sizeof(user)); } else { cout<<"该账户已销户,操作无效"<<endl; } } } return;}/********************************************功能描述:改密。*输入参数:location-用户数据位置*输出参数:user-用户类*返回值:无*其他说明:用户密码被改变。*******************************************/void Bank::updatePassword(){ User user; long location; int iPass1,iPass2; location = getUser(); //根据账号查询用户,返回用户的偏移量 if(location>=0) //说明id账户存在 { if(user.isNormalUser()) { dataFile.seekg(location); dataFile.read((char *)&user,sizeof(User)); user.showName(); if(user.passwordIsRight()) { cout<<"新密码:"; iPass1=inputPassword(); //输入密码1 cout<<"确认密码:"; iPass2=inputPassword(); //输入密码2 if(iPass1==iPass2) { user.password=iPass1; cout<<"修改成功!"<<endl; dataFile.seekp(location); dataFile.write((char *)&user,sizeof(User)); } else { cout<<"两次输入不同,修改失败!"<<endl; } } } } return;}/********************************************功能描述:建立索引。*输入参数:user-用户类*输出参数:userIndex-用户索引*返回值:userIndex-用户索引*其他说明:无。*******************************************/void Bank::createIndex(){ User user; dataFile.open("binarydata.dat",ios::out|ios::in|ios::binary); if(!dataFile) { cerr<<"can't open binarydata.dat!"<<endl; exit(1); } //建立索引 dataFile.read((char *)&UserNum,sizeof(UserNum)); maxNum=UserNum * 1.1; userIndex=new UserIndex [maxNum]; //读入数据,建立未排序的索引表 int i, j; long mOffset; for(i=0; i<UserNum; ++i) { mOffset = dataFile.tellg(); dataFile.read((char*)&user, sizeof(user)); userIndex[i].No = user.getaccount(); userIndex[i].offset = mOffset; } UserIndex temp; for (i=0; i<UserNum-1; i++) for(j=0; j<UserNum-i-1; j++) if (userIndex[j].No>userIndex[j+1].No) { temp=userIndex[j]; userIndex[j]=userIndex[j+1]; userIndex[j+1]=temp; } //将建好的索引表通过文件存储 writeIndex(userIndex, UserNum); return ;}/********************************************功能描述:扩大数组。*输入参数:userIndex-用户索引*输出参数:userIndex-用户索引*返回值:无*其他说明:扩大索引。*******************************************/void Bank::EnlargeArray(){ User user; maxNum = UserNum *1.1; userIndex = new UserIndex[maxNum]; int i; long mOffset; for(i=0; i<UserNum; ++i) { mOffset = dataFile.tellg(); dataFile.read((char*)&user, sizeof(user)); userIndex[i].No = user.getaccount(); userIndex[i].offset = mOffset; } return ;}/********************************************功能描述:写入索引。*输入参数:userIndex-用户索引*输出参数:userIndex.idx-索引文件名*返回值:无*其他说明:无。*******************************************/void Bank::writeIndex(UserIndex *ui, int n){ //打开文件 ofstream indexFile("userIndex.idx", ios::out|ios::binary); if(!indexFile) { cerr<<"can't open userIndex.idx!"<<endl; exit(1); } int i; for(i=0; i<n; ++i) { indexFile.write((char*)&ui[i], sizeof(ui[i])); } //关闭文件 indexFile.close(); return;}/********************************************功能描述:寻找用户位置。*输入参数:id-用户账号*输出参数:location-用户数据位置*返回值:无*其他说明:无。*******************************************/long Bank::getUser(){ int id; long location=-1; int low=0,high=UserNum-1,mid; cout<<"账号:"; cin>>id; while(low<=high) { mid = (low+high)/2; if(userIndex[mid].No==id) { location=userIndex[mid].offset; break; //找到了,立即退出循环 } else if (userIndex[mid].No>id) high=mid-1; else low=mid+1; } if (location<0) cout<<"该用户不存在,本次操作失败!"<<endl; return location; //若找到,其值在0~N-1间,否则,保持-1}/******************************************** 版权所有 (C)2015,Annpion。** 文件名称:User.cpp*文件标识:无*内容摘要:该代码实现User类中的各个函数。*其他说明:无*当前版本:V1.0*作者:王耀鹏*完成日期:2015/7/17*******************************************/#include <iostream>#include "Bank.h"using namespace std;/********************************************功能描述:设置User类中的数据成员。*输入参数:acc-用户账号 nam-用户名称 pw-用户密码 bal-用户余额 sta-用户状态*输出参数:user-用户类*返回值:无*其他说明:无。*******************************************/void User::setUser(int acc, char *nam, int pw, double bal,int sta){ account=acc; password=pw; strcpy(name,nam); balance=bal; status=sta;}/********************************************功能描述:显示用户名称。*输入参数:user-用户类*输出参数:无*返回值:无*其他说明:显示姓名。*******************************************/void User::showName(){ cout<<"户主姓名:"<<name<<endl;}void User::showStatus(string prompt){ cout<<prompt<<" "; if(status==0) cout<<"正常"<<endl; else if(status==1) cout<<"挂失"<<endl; else cout<<"销户"<<endl;}/********************************************功能描述:获取用户账号。*输入参数:user-用户类*输出参数:account-用户账号*返回值:无*其他说明:无。*******************************************/int User::getaccount(){ return account;}/********************************************功能描述:显示用户余额。*输入参数:banlance-用户余额 prompt-显示语句*输出参数:无*返回值:无*其他说明:无。*******************************************/void User::showBalance(string prompt){ cout<<prompt<<" "<<balance<<" 元"<<endl;}/********************************************功能描述:核对用户密码。*输入参数:password-用户密码 iPass-输入密码*输出参数:right-判断对错*返回值:true-正确,false-错误*其他说明:无。*******************************************/bool User::passwordIsRight(){ int iPass; bool right = true; cout<<"输入密码:"; iPass=inputPassword(); if(iPass!=password) { right = false; cout<<"输入密码错误,不能继续操作!"<<endl; } return right;}/********************************************功能描述:判断用户状态。*输入参数:status-用户状态*输出参数:normal-判断用户状态*返回值:true-正常,false-异常*其他说明:无。*******************************************/bool User::isNormalUser(){ bool normal = true; if(status!=0) { normal = false; cout<<"该账户处于"<<(status==1?"挂失":"销户")<<"状态,不能继续操作..."<<endl; } return normal;}/******************************************** 版权所有 (C)2015,Annpion。** 文件名称:Word.cpp*文件标识:无*内容摘要:该代码实现普通函数。*其他说明:无*当前版本:V1.0*作者:王耀鹏*完成日期:2015/7/17*******************************************/#include <iostream>#include <fstream>#include <conio.h>#include <cstdlib>#include <cstring>#include <ctype.h>#include "Bank.h"using namespace std;/********************************************功能描述:验证业务员密码。*输入参数:sNameInFile-业务员姓名 sPassInFile-业务员密码 sName-业务员输入姓名 sPass-业务员输入密码*输出参数:right-判断正误*返回值:1-成功,0-失败*其他说明:无。*******************************************/int pass(){ char sNameInFile[20]; //由文件中读出的业务员用户名 char sPassInFile[20]; //文件中保存的密码,这一版本中,用字符保存密码 ifstream infile("password.txt",ios::in); if(!infile) { cout<<"password file cannot open!"<<endl; exit(1); } infile>>sNameInFile>>sPassInFile; infile.close(); char sName[20]; //业务员登录时输入的用户名 char sPass[20]; //业务员登录时输入的密码 char ch; int iTry=3; //进入系统时尝试的次数 int right = 0; //要返回的结果:0-不正确 1-正确 //进入系统,密码三次不对将退出 do { cout<<"请输入业务员用户名:"; cin>>sName; cout<<"请输入密码:"; int i=0; while((ch=getch())!='\r') //getch在接受输入后,不在屏幕上显示 { sPass[i++]=ch; putchar('*'); //接受任何字符,屏幕上只显示* } sPass[i]='\0'; fflush(stdin); cout<<endl; if(strcmp(sPass,sPassInFile)==0&&strcmp(sName,sNameInFile)==0) { right = 1; break; } else { iTry--; if(iTry>0) cout<<"超过3次将退出,你还可以尝试"<<iTry<<"次!"<<endl; else { cout<<"对不起,你不能进入系统"<<endl;; } } } while(iTry); return right;}/*关于getch()的一点说明:所在头文件:conio.h函数用途:从控制台读取一个字符,但不显示在屏幕上函数原型:int getch(void)返回值:读取的字符在不同平台,输入回车,getch()将返回不同数值,而getchar()统一返回10(即\n)1)windows平台下ENTER键会产生两个转义字符 \r\n,因此getch返回13(\r)。2)unix、 linux系统中ENTER键只产生 \n ,因此getch返回10(\n)。3)MAC OS中ENTER键将产生 \r ,因此getch返回13(\r)。为避免键盘缓存区中未读出的字符影响程序,用fflush(stdin);清除输入缓存区*//********************************************功能描述:选择功能。*输入参数:i-功能序号*输出参数:i-功能序号*返回值:1-开户,2-销户,3-存款,4-取款,5-查询,6-转账,7-挂失,8-解挂,9-改密,0-退出*其他说明:无。*******************************************/int chooseInMenu(){ int i; while(1) { cout<<endl;; cout<<"+----------------------------+"<<endl; cout<<"+ 1 开户 2 销户 3 存款 +"<<endl; cout<<"+ 4 取款 5 查询 6 转账 +"<<endl; cout<<"+ 7 挂失 8 解挂 9 改密 +"<<endl; cout<<"+ 0 退出 +"<<endl; cout<<"+----------------------------+"<<endl; cout<<"请输入操作指令:"; cin>>i; if(i>=0 && i<=9) break; else cout<<"请重新选择功能"<<endl;; } return i;}/*功能:输入密码返回值:整型的密码值技术说明:(1)此功能在多个模块中都要用到且功能单一,故分离出来,单独作业一个函数(2)为了便于在输入中只显示*,接受输入时以字符形式输入,而后转为对应的整型数(3)规定密码由不全为0的6位数字构成(当开头是'0'时,实际不足6位),一旦输入错误将重新输入附:在实际的系统中,密码通常用字符串描述,即使只允许出现数字字符,本例仅作为参考*//********************************************功能描述:输入密码。*输入参数:iPass-用户密码*输出参数:iPass-用户密码*返回值:iPass-用户密码*其他说明:输入的密码在显示时呈星号。*******************************************/int inputPassword(){ char ch; //接收字符形式密码 int iPass=0; //要转换为数字 int i; while(1) { for(i=0; i<6; i++) { ch=getch(); //输入但不显示 putchar('*'); //输出* if(isdigit(ch)) iPass=iPass*10+(ch-'0'); else { iPass=0; break; //退出for循环后,再次接受 } } fflush(stdin); //清除键盘缓存区中已经有的输入 cout<<endl;; if(iPass==0) //此条件成立可能由两种情况引起:输入了非数字字符被直接重置为0,或6位全0后正常退出for循环 { cout<<"密码要求全为数字,且不能全0!"<<endl;; cout<<"请重新输入密码: "; } else break; } return iPass;}
运行结果:
0 0
- <2015年大一C++实训项目>银行储蓄系统
- 大一c++程序设计实训 银行储蓄系统
- 【实训项目】银行储蓄系统
- 实训项目-银行储蓄系统
- 实训项目-银行储蓄系统
- 实训项目银行储蓄系统
- 实训项目--银行储蓄系统
- 实训项目--银行储蓄系统
- 实训项目--银行储蓄系统
- 实训项目--银行储蓄系统
- 【实训项目】银行储蓄系统
- C++项目实训:银行储蓄系统
- C语言项目—银行储蓄系统
- 实训项目——银行储蓄系统
- 实训项目——银行储蓄系统
- 程序设计项目实训——银行储蓄系统
- ##..C++程序设计项目实训——银行储蓄系统
- 实训项目-银行储蓄业务管理系统2015/07/15
- 请千万当心:警惕云使用过程中的分析瘫痪问题
- 学习网页网站
- 关于Android SDK Manager更新速度慢的解决方法
- Genymotion不能成功开启Android5.0模拟器的解决方案
- 【VB】显示本地机器名(机房问题)
- <2015年大一C++实训项目>银行储蓄系统
- GRE写作必备句型
- 手写数字识别【QT+OpenCV】
- 打哈欠补肾法
- Intent的定义及用法
- Activity 的 taskAffinity, allowTaskReparenting, singleTask 属性的应用分析
- 网络编程
- c++课程实训 银行储蓄系统
- Looper、Message、Handler