纯手工打造 难为情的是很多借鉴了贺老的参考解答 希望能在扩展中做出自己的风格
代码如下
main.cpp
#include <iostream>
#include "Bank.h"
using namespace std;
int main()
{
cout<<"+---------------------------------------+"<<endl;
cout<<"+\t欢迎使用neemaby银行系统 \t+"<<endl;
cout<<"+---------------------------------------+"<<endl<<endl;
Bank b;
if (pass())
{
Bank b;
b.work();
}
return 0;
}
Bank.h
#ifndef BANK_H_INCLUDED
#define BANK_H_INCLUDED
#include <cstring>
#include <iostream>
using namespace std;
const int upNum=2000;//本系统暂设最多支持2000个账户
int choosemenu();
int pass();//通过业务员账号
int inputcode();//使密码以*号显示
class user
{
public:
void set_user(int acc, string nam, int pw, double bal,int sta);
void show_name();//显示用户信息
void show_balance();//显示余额
bool passwordIsRight();//判断密码和账户是否相符
bool isNormalUser();
friend class Bank;
private:
int ACCOUNT;//用户账户
string NAME;//用户的名字
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();//更改密码
int getUser();//输入账号查询用户,返回用户在对象数组中的下标
private:
int N;//实际用户数目
user users[upNum];
};
#endif // BANK_H_INCLUDED
Bank.cpp
#include "Bank.h"
#include <iostream>
#include <cstring>
#include <fstream>
#include <cstdlib>
using namespace std;
Bank::Bank()//开机时从文件中读数据,存在数组中
{
ifstream infile("account.dat",ios::in);
if (!infile)
{
cerr<<"open account.dat error!"<<endl;
exit(1);
}
int i=0;
int acc;//账号
string nam;
int pw;
double bal;//金额
int sta;//状态
while (infile>>acc>>nam>>pw>>bal>>sta) //读取成功时
{
users[i].set_user(acc,nam,pw,bal,sta);
i++;
}
N=i;//用静态数据成员储存
infile.close();
}
Bank::~Bank()//关机前将数据写入到文件中
{
ofstream outfile("account.dat",ios::out);
if (!outfile)
{
cerr<<"open account.dat error!"<<endl;
exit(1);
}
int i=1;
for (i=0; i<N; i++)
{
outfile<<users[i].ACCOUNT<<" ";
outfile<<users[i].NAME<<" ";
outfile<<users[i].PASSWORD<<" ";
outfile<<users[i].BALANCE<<" ";
outfile<<users[i].STATUS<<" ";
}
outfile.close();
}
void Bank::work()
{
int iChoice;//选择
do
{
iChoice = choosemenu();
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);
}
void Bank::openAccount()//开户
{
if(N==upNum)
{
cout<<"用户数已经达到上限,无法再开户";
return;
}
int acc; //账号
string nam; //姓名
int pw1,pw2; //密码
double bal; //金额
int sta; //状态
cout<<"开户中…"<<endl;
acc=10001+N;
cout<<"账号:"<<acc<<endl;
cout<<"户主姓名:";
cin>>nam;
cout<<"密码:";
pw1=inputcode(); //输入密码1
cout<<"确认密码:";
pw2=inputcode(); //输入密码2
if(pw1==pw2)
{
sta=0; //状态“正常”
cout<<"存款金额:";
cin>>bal;
users[N].set_user(acc, nam, pw1, bal, sta);
N++; //正式用户数增加1
cout<<"开户成功!"<<endl;
}
else
{
cout<<"两次密码不一致,未成功开户!"<<endl; //没有N++,则读入的值无效
}
}
void Bank::cancelAccount()//注销账户
{
int getU;
getU = getUser(); //根据账号查询用户,返回用户的下标
if(getU>=0) //说明id账户存在
{
users[getU].show_name();
if(users[getU].passwordIsRight())
{
cout<<"余额:";
users[getU].show_balance(); //显示金额
cout<<"是否确认销户(y/n)?";
if(tolower(getchar())=='y')
{
cout<<"销户成功!您的余额";
users[getU].show_balance();
cout<<"将被全部取出!"<<endl;
users[getU].BALANCE=0; //取款后余额变0
users[getU].STATUS=2; //状态变为注销
}
else
{
cout<<"你取消了操作,销户失败!"<<endl;
}
fflush(stdin); //清除了getchar()时在键盘缓存中的遗留,以免影响后续操作
}
}
}
void Bank::save()//存款
{
int getU;
double money;
getU = getUser(); //根据账号查询用户,返回用户的下标
if(getU >=0) //说明id账户存在
{
if(users[getU].STATUS==0)
{
users[getU].show_name();
cout<<"输入存款额:";
cin>>money;
users[getU].BALANCE+=money;
cout<<"存款后,您的账户将有金额:";
users[getU].show_balance();
}
else if(users[getU].STATUS==1)
{
cout<<"该用户处于挂失状态,存款失败!"<<endl;
}
else
{
cout<<"该用户已经销户,存款失败!"<<endl;
}
}
return;
}
void Bank::withdraw()//取款
{
int getU ;
double money;
getU = getUser(); //根据账号查询用户,返回用户的下标
if(getU >=0) //说明id账户存在
{
if(users[getU ].isNormalUser())
{
users[getU ].show_name();
if(users[getU ].passwordIsRight())
{
cout<<"输入取款额:";
cin>>money;
if(money>users[getU ].BALANCE) //亲,不玩透支
{
cout<<"余额不足,取款失败!"<<endl;
}
else
{
users[getU ].BALANCE-=money;
cout<<"取款后,余额为:";
users[getU ].show_balance();
}
}
}
}
return;
}
void Bank::showAccount()//查询账户
{
int getU ;
string sta[3]= {"正常","挂失","已经销户"};
getU = getUser(); //根据账号查询用户,返回用户的下标
if(getU >=0) //说明id账户存在
{
users[getU ].show_name();
if(users[getU ].passwordIsRight())
{
cout<<"账户余额为:";
users[getU ].show_balance();
cout<<"状态:"<<sta[users[getU ].STATUS]<<endl;
}
}
return;
}
void Bank::transferAccounts()//转账
{
int Win,Wout;
double money;
cout<<"转账自";
Wout= getUser();
if(Wout>=0)
{
if(users[Wout].isNormalUser())
{
users[Wout].show_name();
if(users[Wout].passwordIsRight())
{
cout<<"输入转账金额:";
cin>>money;
if(money>users[Wout].BALANCE) //防止透支
{
cout<<"余额不足,转账失败!"<<endl;
}
else
{
cout<<"转出到";
Win = getUser();
if(Win>=0)
{
if(users[Win].isNormalUser())
{
users[Wout].BALANCE-=money;
users[Win].BALANCE+=money;
cout<<"转账后,您的余额为:";
users[Wout].show_balance();
}
}
}
}
}
}
}
void Bank::reportLoss()//挂失
{
int getU;
getU = getUser(); //根据账号查询用户,返回用户的下标
if(getU >=0) //说明id账户存在
{
users[getU ].show_name();
if(users[getU ].passwordIsRight())
{
if(users[getU ].STATUS==0)
{
users[getU ].STATUS=1;
cout<<"挂失成功"<<endl;
}
else if(users[getU ].STATUS==1)
{
cout<<"该账户已经处于挂失状态"<<endl;
}
else
{
cout<<"该账户已销户,不能挂失"<<endl;
}
}
}
return;
}
void Bank::cancelLoss()//解挂
{
int getU;
getU=getUser();
if (getU>=0)
{
users[getU].show_name();
if(users[getU ].passwordIsRight())
{
if(users[getU ].STATUS==1)
{
users[getU ].STATUS=0;
cout<<"解挂成功"<<endl;
}
else if(users[getU ].STATUS==0)
{
cout<<"该账户无需解挂"<<endl;
}
else
{
cout<<"该账户已销户,不能挂失"<<endl;
}
}
}
return;
}
void Bank::updatePassword()//更改密码
{
int getU,pw1,pw2;
getU=getUser();
if (getU>=0)
{
users[getU].show_name();
if(users[getU ].passwordIsRight())
{
cout<<"请输入新密码:";
pw1=inputcode();
cout<<"请重复密码:";
pw2=inputcode();
if (pw1==pw2)
{
users[getU].PASSWORD=pw1;
cout<<"密码修改成功!"<<endl;
}
else
{
cout<<"两次密码不一致,未成功开户!"<<endl;
}
}
}
return;
}
int Bank::getUser()//输入账号查询用户,返回用户在对象数组中的下标
{
//使用二分查找法查找账户
int id,mid;
int ind=-1,high=N-1,low=0;
cout<<"账号:";
cin>>id;
while(low<=high)
{
mid=(low+high)/2;
if (users[mid].ACCOUNT==id)
{
ind=mid;
break;
}
else if (users[mid].ACCOUNT>id)
high=mid-1;
else
low=mid+1;
}
if(ind<0)
cout<<"该用户不存在,本次操作失败!"<<endl;
return ind; //若找到,其值在0~N-1间,否则,保持-1
}
user.cpp
#include "Bank.h"
#include <iostream>
#include <cstring>
#include <fstream>
#include <cstdlib>
using namespace std;
void user::set_user(int acc,string nam,int pw,double bal,int sta)
{
ACCOUNT=acc;
NAME=nam;
PASSWORD=pw;
BALANCE=bal;
}
void user::show_name()
{
cout<<"姓名:"<<NAME<<endl;
}
void user::show_balance()//显示余额
{
cout<<BALANCE<<" 元"<<endl;
}
bool user::passwordIsRight()//校验密码,正确返回true
{
int pw;
bool right=true;
cout<<"输入密码:";
pw=inputcode();
if (pw!=PASSWORD)
{
right=false;
cout<<"密码错误,无法继续操作!"<<endl;
}
return right;
}
bool user::isNormalUser()//判断是否处于“正常”,是则返回true,否则返回false
{
bool normal=true;
if(STATUS!=0)
{
normal=false;
cout<<"该账户处于"<<(STATUS==1?"挂失":"销户")<<"状态,不能继续操作!"<<endl;
}
return normal;
}
work.cpp
#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <conio.h> //getch要用
#include <cstring>
#include "Bank.h"
using namespace std;
int choosemenu()
{
int i;
while(1)
{
cout<<endl;;
cout<<"+--------------------------------------+"<<endl;
cout<<"+ 1 开户\t2 销户\t\t3 存款 +"<<endl;
cout<<"+ 4 取款\t5 查询\t\t6 转账 +"<<endl;
cout<<"+ 7 挂失\t8 解挂\t\t9 改密 +"<<endl;
cout<<"+ 0 退出\t\t\t +"<<endl;
cout<<"+--------------------------------------+"<<endl;
cout<<"请输入操作指令:";
cin>>i;
if(i>=0 && i<=9)
break;
else
cout<<"请重新选择功能"<<endl;;
}
return i;
}
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;
}
int inputcode()//使密码以*号显示
{
char ch;
int iPass=0;//用于将输入的字符型数字转换为数字型数字
while(1)
{
for(i=0; i<6; i++)
{
ch=getch();
putchar('*'); //输入后不显示数字而输出*
if(isdigit(ch)) //!!isdigit(ch)的使用
iPass=iPass*10+(ch-'0');
else
{
iPass=0;
break; //退出for循环后,再次接受
}
}
fflush(stdin); //!!清除键盘缓存区中已经有的输入,fflush(stdin)的使用
cout<<endl;;
if(iPass==0) //此条件成立可能由两种情况引起:输入了非数字字符被直接重置为0,或6位全0后正常退出for循环
{
cout<<"密码要求全为数字,且不能全0!"<<endl;;
cout<<"请重新输入密码: ";
}
else
break;
}
return iPass;
}
学习心得
work.cpp中:
1.fflush(stdin)
fflush用于清空缓冲流,虽然一般感觉不到,但是默认printf是缓冲输出的。 fflush(stdout),使stdout清空,就会立刻输出所有在缓冲区的内容。 fflush(stdout)这个例子可能不太明显,但对stdin很明显。 如下语句: int a,c; scanf("%d",&a); getchar(); 输入: 12(回车) 那么 a=12 ,c= '\n' 而: int a,c; scanf("%d",&a); fflush(stdin); getchar(); 输入: 12(回车) 那么a=12, c暂时未得到输入值,还需要再输入c,因为getchar也是缓冲输入,'\n'本还在缓冲区,但是被清空了。 另外fflush不能作用于重定向输入流。
2.getch()
这个函数是一个不回显函数,当用户按下某个字符时,函数自动读取,无需按回车,有的C语言命令行程序会用到此函数做游戏,但是这个函数并非标准函数,要注意移植性!
getch():
所在头文件:conio.h
函数用途:从控制台读取一个字符,但不显示在屏幕上
函数原型:int getch(void)
返回值:读取的字符
例如:
char ch;或int ch;
_getch();或ch=_getch();
用_getch();会等待你按下任意键,再继续执行下面的语句;
用ch=_getch();会等待你按下任意键之后,把该键字符所对应的ASCII码赋给ch,再执行下面的语句。
3.isdight()
isdigit()函数包含在ctype.h头文件中, 原型: int isdigit(char c); 用法:#include <ctype.h> 功能:判断字符c是否为数字 说明:当c为数字0-9时,返回非零值,否则返回零。 这个函数是判断某一个字符是否为数字,可以用一个字符数组接受输入的字符,然后循环判断每一个字符是否为数字,如果其中一个不是数字,那么返回0,否则返回非0; 如果想要实现负数或者小数的判断,需要自己在此基础设计代码,(判断小数点的个数和负数符号-) 补充段代码,可以判断负数和小数: #include<stdio.h> #include<ctype.h> void main() { char a[10]; int i,j,flag=0; /*flag标记小数点个数,如果超过一个,那么就不是数字*/ printf("input a number:\n"); scanf("%s",a); for(i=0;a[i]!=0;i++) { if(i==0&&(a[i]=='+'||a[i]=='-')) { i++; continue; } /*如果第一个字符为+或-,不判断为非数字,可能是符号标志,继续向下判断*/ if(a[i]=='.') { flag++; if(flag>1) /*如果小数点个数超过一个,则表示不是数字*/ { break; } else if(flag==1) /*如果小数点个数为1个,则可能为小数,继续判断*/ { continue; } } j=isdigit(a[i]); if(j==0) { break; } } if(j!=0) printf("%s yes",a); else printf("%s no",a); getch(); }