头文件:bank.h
/*
*版权所有:Copyright (c)2015,烟台大学计算机与控制工程学院
*All rights reserved.
*
*文件名称:bank.h
*文件标识:无
*内容摘要:该代码用于获取满足后缀要求的第一个文件
*其他说明:无
*当前版本:V1.0
*作 者:徐洪祥
*完成日期:2015年7月17日
*/
#ifndef BANK_H_INCLUDED
#define BANK_H_INCLUDED
#include <cstring>
using namespace std;
const int upnum=2000;//系统最多容纳的用户数
class Bank;
class User
{
public:
void setuser(int acc,string nam,string idn,double phnu,string add,int pw,double bal,int sta);//赋值
void showuser();//显示名字
void showbalance(string prompt);//显示余额
bool passwordright();//验证密码
bool staisnor();//验证状态,处于正常状态时返回true,其他情形返回false并提示
friend class Bank;//将Bank声明为友元类,方便其访问数据成员
private:
int account;//账户
string name;//姓名
string idnumber;//身份证号
double phonenumber;//电话号码
string address;//地址
int password;//密码
double balance;//余额
int status;//状态 0-正常 1-挂失 2-销户
};
class Bank
{
public:
Bank();//构造函数
~Bank();//析构函数
void work();//业务驱动
void openacc();//开户
void cancelacc();//销户
void save();//存款
void withdraw();//取款
void showacc();//查询余额
void transferacc();//转账
void reloss();//挂失
void cancelloss();//解除挂失
void repassword();//更改密码
int getuser(); //输入账号查询用户,返回用户在对象数组中的下标
private:
int num; //实际的用户数目
User users[upnum];
};
int inputpassword();//输入密码
int pass();//业务员
int choosemenu();//服务列表
#endif // BANK_H_INCLUDED
主函数:main.cpp
/*
*版权所有:Copyright (c)2015,烟台大学计算机与控制工程学院
*All rights reserved.
*
*文件名称: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;
}
基础函数:work.cpp
/*
*版权所有:Copyright (c)2015,烟台大学计算机与控制工程学院
*All rights reserved.
*
*文件名称:work.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;
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;
}
/*
功能:验证用户密码
返回值:密码正确,返回1;
不能通过密码验证,返回0
*/
int pass()
{
char namefile[20]; //由文件中读出的业务员用户名
char passfile[20]; //文件中保存的密码,这一版本中,用字符保存密码
ifstream infile("password.txt",ios::in);
if(!infile)
{
cout<<"password.txt open error."<<endl;
exit(1);
}
infile>>namefile>>passfile;
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,passfile)==0&&strcmp(sname,namefile)==0)
{
right=1;
break;
}
else
{
itry--;
if(itry>0)
cout<<"超过三次将退出,你还可以尝试"<<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);清除输入缓存区
*/
/*
功能:显示菜单并由业务员选择
返回值:用户选择的功能,范围0-9
*/
int choosemenu()
{
int i;
while(1)
{
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;
}
user.cpp
/*
*版权所有:Copyright (c)2015,烟台大学计算机与控制工程学院
*All rights reserved.
*
*文件名称:user.cpp
*文件标识:无
*内容摘要:该代码用于获取满足后缀要求的第一个文件
*其他说明:无
*当前版本:V1.0
*作 者:徐洪祥
*完成日期:2015年7月17日
*/
#include <iostream>
#include "bank.h"
using namespace std;
void User::setuser(int acc,string nam,string idn,double phnu,string add,int pw,double bal,int sta)
{
account=acc;
name=nam;
idnumber=idn;
phonenumber=phnu;
address=add;
password=pw;
balance=bal;
status=sta;
}
void User::showuser()
{
cout<<"用户姓名:"<<name<<endl;
}
void User::showbalance(string prompt)//显示余额
{
cout<<prompt<<" "<<balance<<"元"<<endl;
}
bool User::passwordright()//验证密码
{
bool t=true;
int pass;
cout<<"请输入密码:"<<endl;
pass=inputpassword();
if(pass!=password)
{
t=false;
cout<<"密码错误!"<<endl;
}
return t;
}
bool User::staisnor()//判断用户当前状态
{
bool nor=true;
if(status!=0)
{
nor=false;
cout<<"该账户处于"<<(status==1?"挂失":"销户")<<"状态"<<endl;
}
return nor;
}
bank.cpp
/*
*版权所有:Copyright (c)2015,烟台大学计算机与控制工程学院
*All rights reserved.
*
*文件名称:bank.cpp
*文件标识:无
*内容摘要:该代码用于获取满足后缀要求的第一个文件
*其他说明:无
*当前版本:V1.0
*作 者:徐洪祥
*完成日期:2015年7月17日
*/
#include <iostream>
#include <fstream>
#include <cstdlib>
#include "bank.h"
#include <ctype.h>
using namespace std;
/*
功能:用构造函数读取文件中保存的业务数据
*/
Bank::Bank()
{
ifstream infile("account.txt",ios::in);
if(!infile)
{
cerr<<"open error"<<endl;
exit(1);
}
int i=0;
int acc;//账号
string nam;//姓名
string idn;//身份证号
double phnu;//电话号码
string add;//地址
int pw;//密码
double bal;//余额
int sta;//状态
while(infile>>acc>>nam>>idn>>phnu>>add>>pw>>bal>>sta)//当读取成功……
{
users[i].setuser(acc,nam,idn,phnu,add,pw,bal,sta);
i++;
}
num=i;//用静态数据成员
infile.close();
}
/*
功能:用析构函数,在退出系统时,将数据保存到文件中
*/
Bank::~Bank()
{
ofstream outfile("account.txt",ios::out);
if(!outfile) //测试文件打开操作是否成功,不成功则提示后退出。
{
cerr<<"open error"<<endl;
exit(1);
}
for(int i=0; i<num; i++)
{
outfile<<users[i].account<<" ";
outfile<<users[i].name<<" ";
outfile<<users[i].idnumber<<" ";
outfile<<users[i].phonenumber<<" ";
outfile<<users[i].address<<" ";
outfile<<users[i].password<<" ";
outfile<<users[i].balance<<" ";
outfile<<users[i].status<<'\n';
}
outfile.close();
}
void Bank::work()//功能:办理业务
{
int choose; //用于选择系统功能
do
{
choose=choosemenu();//从菜单中获得功能代码
switch(choose)
{
case 1:
openacc();//开户
break;
case 2:
cancelacc();//注销账户
break;
case 3:
save();//存款
break;
case 4:
withdraw();//取款
break;
case 5:
showacc();// //查询余额
break;
case 6:
transferacc();//转账
break;
case 7:
reloss();//挂失
break;
case 8:
cancelloss();//解除挂失
break;
case 9:
repassword();//修改密码
break;
case 0:
cout<<"欢迎下次再来"<<endl;
}
}
while(choose);
}
void Bank::openacc()//开户
{
if(num==upnum)
{
cout<<"用户已达上限,请以后再来"<<endl;
return;
}
int acc;//账户
string nam;//姓名
string idn;//身份证号
double phnu;//电话号码
string add;//地址
int pw;//密码
double bal;//余额
int sta;//状态
cout<<"正在开户、、、、"<<endl;
acc=10001+num;
cout<<"账户名:"<<acc<<endl;
cout<<"用户名:"<<endl;
cin>>nam;
cout<<"身份证号:"<<endl;
cin>>idn;
cout<<"手机号:"<<endl;
cin>>phnu;
cout<<"家庭地址:"<<endl;
cin>>add;
int pass1,pass2;
cout<<"请输入密码:";
pass1=inputpassword(); //输入密码1
cout<<"请确认密码:";
pass2=inputpassword(); //输入密码2
if(pass1==pass2)
{
pw=pass1;
sta=0;//账户状态为“正常”
cout<<"存入金额:";
cin>>bal;
users[num].setuser(acc,nam,idn,phnu,add,pw,bal,sta);
num++;//正式用户数增加1,确认了新用户已经加入
cout<<"开户成功"<<endl;
}
else
cout<<"两次输入密码不一致,开户不成功"<<endl;
}
void Bank::cancelacc()//销户
{
int who;//查找到该账号在数组中对应的下标
who=getuser();//根据账号查询用户,返回用户的下标
if(who>=0)//说明id账户存在
{
users[who].showuser();
if(users[who].passwordright())
{
users[who].showbalance("余额"); //提示"余额"二字,显示金额
cout<<"确认销户(y/n)?";
if(tolower(getchar())=='y')
{
users[who].showbalance("销户成功,本次取款金额为:");
users[who].balance=0; //取款后余额变0
users[who].status=2; //状态变为注销
}
else
cout<<"用户已取消操作,销户失败."<<endl;
fflush(stdin);//清除了getchar()时在键盘缓存中的遗留,以免影响后续操作
}
}
}
void Bank::save()//存款
{
int who;
double money;
who=getuser();
if(who>=0)
{
if(users[who].status==0)
{
users[who].showuser();
cout<<"请输入存款金额:";
cin>>money;
ofstream file("save.txt",ios::app);
if(!file)
{
cerr<<"save open error!"<<endl;
exit(1);
}
file<<users[who].account<<"存入"<<money<<endl;
file.close();
users[who].balance+=money;
users[who].showbalance("存入成功,余额为:");
}
else if(users[who].status==1)
cout<<"该用户处于挂失状态,存款失败."<<endl;
else
cout<<"该用户已经销户,存款失败."<<endl;
}
return;
}
void Bank::withdraw()//取款
{
int who;
double money;
who=getuser();
if(who>=0)
{
if(users[who].staisnor())
{
users[who].showuser();
if(users[who].passwordright())
{
cout<<"请输入取款额度:";
cin>>money;
ofstream file("save.txt",ios::app);
if(!file)
{
cerr<<"save open error!"<<endl;
exit(1);
}
file<<users[who].account<<"取出"<<money<<endl;
file.close();
if(money>users[who].balance)
cout<<"余额不足,取款失败."<<endl;
else
{
users[who].balance-=money;
users[who].showbalance("取款后,余额为:");
}
}
}
}
return ;
}
void Bank::showacc()//查询余额
{
int who,a;
char b;
string rep;
string sta[3]= {"正常","挂失","已经销户"};
who=getuser(); //根据账号查询用户,返回用户的下标
if(who>=0)//说明id账户存在
{
users[who].showuser();
if(users[who].passwordright())
{
users[who].showbalance("余额:");
cout<<"状态:"<<sta[users[who].status]<<endl;
cout<<"是否查看账户记录?(y/n)"<<endl;
cin>>b;//输入y或n
if(b=='y')
{
ifstream file("save.txt",ios::in);
if(!file)
{
cerr<<"save open error!"<<endl;
exit(1);
}
while(file>>a)
{
if(a==users[who].account)//输入的是已存在账号
{
file>>rep;
cout<<rep<<" ";
cout<<endl;
}
else
file>>rep;
}
file.close();
}
}
}
return ;
}
void Bank::transferacc()//转账
{
int whoout,whoin;
double money;
cout<<"转出账户:";
whoout=getuser();
if(whoout>=0)
{
if(users[whoout].staisnor())//判断状态
{
users[whoout].showuser();
if(users[whoout].passwordright())
{
cout<<"输入转账金额:";
cin>>money;
if(money>users[whoout].balance)
cout<<"余额不足,转账失败."<<endl;
else
{
cout<<"转账到:";
whoin=getuser();
if(whoin>=0)
{
if(users[whoin].staisnor())
{
users[whoout].balance-=money;
users[whoin].balance+=money;
ofstream file("save.txt",ios::app);
if(!file)
{
cerr<<"save open error!"<<endl;
exit(1);
}
file<<users[whoout].account<<" 转出"<<money<<endl;
file<<users[whoin].account<<"存入"<<money<<endl;
file.close();
users[whoout].showbalance("转账后,余额为:");
}
}
}
}
}
}
return;
}
void Bank::reloss()//挂失
{
int who;
who=getuser();
if(who>=0)
{
users[who].showuser();
if(users[who].passwordright())
{
if(users[who].status==0)
{
users[who].status=1;
cout<<"挂失成功"<<endl;
}
else if(users[who].status==1)
cout<<"该账户已经处于挂失状态."<<endl;
else
cout<<"该账户已经销户,挂失失败."<<endl;
}
}
return ;
}
void Bank::cancelloss()//解除挂失
{
int who;
who=getuser();
if(who>=0)
{
users[who].showuser();
if(users[who].passwordright())
{
if(users[who].status==0)
cout<<"该账户处于正常状态,无需解除挂失."<<endl;
else if(users[who].status==1)
{
users[who].status=0;
cout<<"解除挂失成功."<<endl;
}
else
cout<<"该账户已经销户,解除挂失失败."<<endl;
}
}
return ;
}
void Bank::repassword()//更改密码
{
int who;
int pass1,pass2;
who=getuser();
if(who>=0)
{
users[who].showuser();
if(users[who].passwordright())
{
cout<<"新密码:";
pass1=inputpassword();
cout<<"再次输入:";
pass2=inputpassword();
if(pass1==pass2)
{
users[who].password=pass1;
cout<<"修改密码成功,请牢记新密码."<<endl;
}
else
cout<<"两次密码不同,修改失败."<<endl;
}
}
return ;
}
/*
功能:输入账号查询用户,返回用户在数组中的下标
入口参数:要查询用户的账号
返回值:如果该用户存在,返回该用户在数组中的下标,否则,返回一个负数(-1)
说明:
由账号自动产生,使按账号有序,本模块采用二分查找
*/
int Bank::getuser()
{
int id;
cout<<"账号:";
cin>>id;
int index=-1;
int low=0,high=num-1,mid;
while(low<=high)
{
mid=(low+high)/2;
if(users[mid].account==id)
{
index=mid;
break; //找到了,立即退出循环
}
else if(users[mid].account>id)
high=mid-1;
else
low=mid+1;
}
if(index<0)
cout<<"该账户不存在."<<endl;
return index;//若找到,其值在0~N-1间,否则,保持-1
}
总结:拿贺老代码参考,拿同学代码参考,终于算是完成了,感觉太力不从心了,越来越意识到自己与学霸的差距,不过也不是完全没有进步,至少对各个部分更加了解,相当于复习了,许多以前忘记、忽略的问题都被重新重视起来,这会对以后的学习有很大的帮助,面临大一期末结束,面临C++结课,是结束,也是新的开始,相信这不会是我们C++的结束,而只是中途的一个小转折,我们会走的更远。