C++第14周项目6——银行系统,用文件永久存储

简介: 课程首页地址:http://blog.csdn.net/sxhelijian/article/details/7910565【项目6 - 银行系统】我们可以实现真正的多用户银行系统了。在具体业务上,不作多的改变,主要改变在用户管理上:  (1)存储用户信息用三个全局数组,并用一个整型全局变量表示当前登录的帐户const int NUM=5; //暂时支持5个用户,其实,可以很多in

课程首页地址:http://blog.csdn.net/sxhelijian/article/details/7910565


【项目6 - 银行系统】我们可以实现真正的多用户银行系统了。在具体业务上,不作多的改变,主要改变在用户管理上:
  (1)存储用户信息用三个全局数组,并用一个整型全局变量表示当前登录的帐户

const int NUM=5;   //暂时支持5个用户,其实,可以很多
int account[NUM]={37001,37002, 37020, 37245,37888}; //帐户
int pwd[NUM]={123456,654321, 456789, 987654, 234432}; //密码
double balance[NUM]={1000., 300, 23.67, 42.30, 56789}; //余额
int accountIndex; //用全局变量保存当前登录的帐户对应的下标

  提示:输入帐户后,在account数组中查找,找不到提示,登录失败;找到后,用accountIndex记住其下标,之后的各种业务中,pwd[accountIndex], balance[accountIndex]是该帐户的相关的信息。
  (2)转帐可以真正实现在两个帐户间的转账了。

  满足(1)和(2)的参考见:http://blog.csdn.net/sxhelijian/article/details/8240764

  (3)-选做题:程序运行完,改变后的数据全丢了!可以建立文件保存有关信息,程序开始时,读入文件中保存的帐户、密码、余额,在程序退出时,再将变化后数据写入到文件中。这种做法更符合实际应用要求,同时,也可以支持更多的用户。(附中的数据可以复制用于自建文本文件,以便于程序中使用。)

参考代码:这部分主要增加两个函数,分别用于从文件中直接读取用户信息(而不是通过初始化给出信息),以及将运行过程中变化了的数据保存到文件中。这两个函数分别为:

//从文件中读取数据,保存到全局数组中
void getInformation()  //用于读取帐户数据
{
	ifstream infile("bank.dat",ios::in);  //以输入的方式打开文件
	if(!infile)       //测试是否成功打开
	{
		cerr<<"不好啦,找不到储户信息了!"<<endl;
		exit(1);
	}
	int i=0;
	while(!infile.eof())
	{
		infile>>account[i]>>pwd[i]>>balance[i];
		++i;
	}
	infile.close();
	accountNum=i;  //用户数目
	return;
}

//退出时,将变化了的数据保存到文件中,下次运行,接着上次的业务继续办下去
void saveInformation() //退出前保存数据
{
	ofstream outfile("bank.dat",ios::out);  //以输入的方式打开文件
	if(!outfile)       //测试是否成功打开
	{
		cerr<<"不好啦,储户信息保存不了了!"<<endl;
		exit(1);
	}
	int i=0;
	while(i<accountNum)
	{
		outfile<<account[i]<<'\t'<<pwd[i]<<'\t'<<balance[i]<<'\n';
		++i;
	}
	outfile.close();
	return;
}

完整的参考解答:
#include<iostream>   
#include<fstream>
using namespace std; 
//用全局变量存储各个帐户的相关信息,便于各函数间共享数据(是一种解决办法)
//直接用变量并不是好方案,后面将引入数组解决
//直接在程序中存储并不是好方案,这些信息要存入文件
const int NUM=100;   //暂时最多支持100个用户,其实,可以很多
int account[NUM]; //帐户
int pwd[NUM]; //密码
double balance[NUM]; //余额
int accountNum;  //实际用户数,由读文件决定
int accountIndex; //用全局变量保存当前登录的帐户对应的下标
int currentAccount; //用全局变量保存当前登录的帐户

//声明自定义函数
int checkStatus();
int seekUser(int);
void work();
void showbalance();
void drawmoney();
void deposit();
void transferAccounts();
void updatePassword();
void getInformation();  //用于读取帐户数据
void saveInformation(); //退出前保存数据

int main()  
{  
	int status;
	char ch;
	cout<<"贺家银行欢迎您光临……(需要看bank.dat中的数据确定,这本是银行中的绝密数据!)"<<endl;
	getInformation();  //用于读取开户数据
	while(1)  //支持用户多次登录办理业务
	{
		status=checkStatus();
		switch(status)
		{
		case 1:  //密码正确 
			work();
			break;
		case 2:  //自行终止登录
			cout<<"欢迎下次光临……"<<endl;
			break;
		case 3:
			cout<<"请确认帐号后再来……"<<endl;
			break;
		case 4:
			cout<<"吞卡,请联系就近网点解决……"<<endl;
		}
		cout<<"=====要退出系统,请按键Q,其他键继续下一位用户登录======"<<endl;
		fflush( stdin );  //清空输入缓冲区,否则getchar()自动获得
		ch=getchar();
		if(ch=='q'||ch=='Q')break;
	}
	saveInformation();
	return 0;
}

/*检验密码
 *返回值约定:
1 - 用户名、密码正确,可以进一步工作
2 - 用户名放弃登录正常退出
3 - 用户名不对退出
4 - 三次登录失败吞卡后退出
*/
int checkStatus()
{
	int iStatus=4;		//默认吞卡的结局
	int iPass;
	int num=1;
	char goOn;
	cout<<"请输入帐户";
	cin>>currentAccount;  //currentAccount是全局变量
	accountIndex=seekUser(currentAccount);
	if(accountIndex < 0)   //根据seekUser的定义,这表示找不到这个客户
		iStatus=3; 
	else
	{		
		do
		{	
			if(num==1)
				cout<<"请输入密码";
			else
			{
				cout<<"温情提示:这是您第"<<num<<"次输入密码,三次不对将吞卡。"<<endl;
				cout<<"还要继续尝试吗(继续输入Y,退出输入N,之后回车):";
				cin>>goOn;
				if('Y'==goOn||'y'==goOn)
					cout<<"请再次输入密码";
				else
				{
					iStatus=2; //用户放弃登录
					break;
				}
			}
			cin>>iPass;
			num++;
			if(iPass==pwd[accountIndex])   //帐户
			{
				iStatus=1;  //密码对了
				break;
			}
		}while(num<4);  //密码不正确且次数在允许范围内循环
		//如果在循环因为num==4为真而退出,iStatus的值还保持初始3,代表吞卡
	}
	return iStatus; //返回状态
}	

//查找是否存在这个客户,
//如果存在,返回其对应的下标
//如果不存在,返回-1(查找败)
int seekUser(int iAccount)
{
	int i;
	for(i=0;i<accountNum;++i)//用了顺序查找,实际系统中确保account[]有序,进行二分查找
	{
		if(iAccount==account[i])
			break;
	}
	if(i>=accountNum)
		i=-1;  //代表找不到这样的用户
	return i;
}

//处理业务
void work()
{
	char cChoice;
	bool bExit = false;
	do  
	{  
		cout<<endl<<"*  您可以办理下面的业务:"<<endl;  
		cout<<"*  1.查询"<<endl;  
		cout<<"*  2.取款"<<endl;  
		cout<<"*  3.存款"<<endl;
		cout<<"*  4.转账"<<endl;
		cout<<"*  5.修改密码"<<endl;
		cout<<"*  0.退出"<<endl;  
		cout<<"*  请输入(0-4):";  
		cin>>cChoice;
		switch(cChoice)
		{
		case '1':
			showbalance();
			break;  
		case '2':
			drawmoney();
			break;  
		case '3':
			deposit();
			break;  
		case '4':
			transferAccounts();
			break;  
		case '5':
			updatePassword();
			break;  
		case '0':
			cout<<"欢迎您下次来存款. "<<endl;
			bExit=true;
		}		
	}while(!bExit);  
	return;
}

//查询余额
void showbalance()
{
	cout<<"您的当前余额是:"<<balance[accountIndex]<<"元"<<endl;
}

//取款
void drawmoney()
{  
	double money;  
	cout << "请输入取款金额:";  
	cin >> money;  
	//下面不计利息了,从现在起,我们的银行只提供银行卡业务,是定期统一计息的
	if(money<=balance[accountIndex])
	{
		balance[accountIndex]-=money; //取款成功
		cout<<"取款后,您的余额是:"<<balance[accountIndex]<<"元。"<<endl;
	}
	else
	{
		cout<<"您的余额不足,取款失败。"<<endl;
	}
}	
//存款
void deposit()
{
	double money;  
	cout << "请输入存款金额:";  
	cin >> money;  
	//下面不计利息了,从现在起,我们的银行只提供银行卡业务,是定期统一计息的
	balance[accountIndex]+=money; //取款成功
	cout<<"存款后,您的余额是:"<<balance[accountIndex]<<"元。"<<endl;
}

//转帐
void transferAccounts()
{
	double money;  
	int iAccount2,iAccount2Index;
	cout << "请输入转帐金额:";
	cin >> money;  
	if(money>balance[accountIndex]) //本行不透支,不能转账
	{
		cout<<"您的余额不足,转账失败。"<<endl;
	}
	else
	{
		cout << "请输入对方帐户:";
		cin >> iAccount2; //应该判断对方帐户的有效性再转账,暂时不做,待以后改进  
		iAccount2Index=seekUser(iAccount2);
		if(iAccount2Index==-1)
			cout<<"对方帐号输入错误,转账失败。"<<endl;
		else
		{
			balance[accountIndex]-=money; //从己方转出
			balance[iAccount2Index]+=money; //转给对方
			//此处应该为对方帐户增加余额,暂时略
			cout<<"转账后,您的余额是:"<<balance[accountIndex]<<"元,对方余额为"<<balance[iAccount2Index]<<"元。"<<endl;
			//实际系统中不似上行那样提示,暴露信息太多了。
		}
	}
}			
//修改密码
void updatePassword()
{
	int p1,p2;
	cout << "请输入新密码:";
	cin >> p1;  
	cout << "请确认新密码:";
	cin >> p2;  
	if(p1==p2)//两次输入相符
	{
		pwd[accountIndex]=p1;   
		cout<<"密码修改成功!"<<endl;
	}
	else
	{
		cout<<"两次输入不一致,密码修改失败。"<<endl;
	}
}

//从文件中读取数据,保存到全局数组中
void getInformation()  //用于读取帐户数据
{
	ifstream infile("bank.dat",ios::in);  //以输入的方式打开文件
	if(!infile)       //测试是否成功打开
	{
		cerr<<"不好啦,找不到储户信息了!"<<endl;
		exit(1);
	}
	int i=0;
	while(!infile.eof())
	{
		infile>>account[i]>>pwd[i]>>balance[i];
		++i;
	}
	infile.close();
	accountNum=i;  //用户数目
	return;
}

//退出时,将变化了的数据保存到文件中,下次运行,接着上次的业务继续办下去
void saveInformation() //退出前保存数据
{
	ofstream outfile("bank.dat",ios::out);  //以输入的方式打开文件
	if(!outfile)       //测试是否成功打开
	{
		cerr<<"不好啦,储户信息保存不了了!"<<endl;
		exit(1);
	}
	int i=0;
	while(i<accountNum)
	{
		outfile<<account[i]<<'\t'<<pwd[i]<<'\t'<<balance[i]<<'\n';
		++i;
	}
	outfile.close();
	return;
}



附:每行三部分,分别代表帐号、密码和余额

37001 888888 4237.14
37002 888888 5832.72
37020 888888 2293.51
37039 888888 2301.64
37054 888888 3973.79
37076 888888 3113.14
37136 888888 1388.44
37145 888888 6859.24
37146 888888 4908.69
37169 888888 72.15
37186 888888 3849.17
37210 888888 6504.1
37234 888888 8881.48
37245 888888 1531.64
37248 888888 9364.73
37284 888888 1332.65
37300 888888 8193.88
37332 888888 9388.03
37367 888888 300.44
37388 888888 9332.52
37405 888888 1025.26
37415 888888 140.32
37428 888888 5896.66
37436 888888 3849.9
37454 888888 3248.8
37470 888888 1230.94
37477 888888 666.61
37538 888888 7203.55
37564 888888 9806.99
37577 888888 1582.34
37592 888888 1969.6
37608 888888 7064.15
37643 888888 8062.96
37649 888888 2583.51
37671 888888 7359.89
37672 888888 8574.99
37737 888888 6071.79
37742 888888 259.45
37787 888888 8283.67
37844 888888 8834.27
37848 888888 8898.72
37860 888888 9492.8
37872 888888 4933.12
37888 888888 3225.68
37904 888888 1932.39
37904 888888 5720.54
37931 888888 6612.89
37967 888888 8995.55
37993 888888 9090.43
37995 888888 2628.41

目录
相关文章
WK
|
1月前
|
机器学习/深度学习 人工智能 算法
那C++适合开发哪些项目
C++ 是一种功能强大、应用广泛的编程语言,适合开发多种类型的项目。它在游戏开发、操作系统、嵌入式系统、科学计算、金融、图形图像处理、数据库管理、网络通信、人工智能、虚拟现实、航空航天等领域都有广泛应用。C++ 以其高性能、内存管理和跨平台兼容性等优势,成为众多开发者的选择。
WK
86 1
|
2月前
|
Ubuntu Linux 编译器
Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV
通过以上步骤,您已经成功在Ubuntu系统下的VS Code中配置了C/C++项目环境,并能够调用OpenCV库进行开发。请确保每一步都按照您的系统实际情况进行适当调整。
570 3
|
2月前
|
Linux C++
Linux c/c++文件的基本操作
在Linux环境下使用C/C++进行文件的基本操作,包括文件的创建、写入、读取、关闭以及文件描述符的定位。
25 0
Linux c/c++文件的基本操作
|
3月前
|
C++ 内存技术
[转]Visual C++内嵌swf文件并播放
[转]Visual C++内嵌swf文件并播放
|
3月前
|
C++
【C++案例】一个项目掌握C++基础-通讯录管理系统
这篇文章通过一个通讯录管理系统的C++项目案例,详细介绍了如何使用C++实现添加、显示、删除、查找、修改和清空联系人等功能。
57 3
|
2月前
|
Linux C++
Linux c/c++文件虚拟内存映射
这篇文章介绍了在Linux环境下,如何使用虚拟内存映射技术来提高文件读写的速度,并通过C/C++代码示例展示了文件映射的整个流程。
65 0
|
2月前
|
Linux C++
Linux c/c++文件移动
这篇文章介绍了在Linux环境下,使用C/C++语言通过命令方式和文件操作方式实现文件移动的方法。
93 0
|
3月前
|
Linux API C++
超级好用的C++实用库之文件目录操作
超级好用的C++实用库之文件目录操作
48 0
|
28天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
50 2
|
1月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
103 5