银行账户管理系统

本文介绍了一个基于C++的银行账户管理系统的设计,包括开户、销户、存款、取款、转账等功能。系统使用面向对象编程,通过文件存储账户信息,并通过身份证号和账号进行操作。在销户时,账号会被回收并可用于其他账户。此外,系统还实现了数据的排序和保存,确保数据的安全和准确性。
摘要由CSDN通过智能技术生成

一、课题背景及实现目标

随着计算机的飞速发展及应用领域的扩大,特别是计算机网络和电子商务的发展,极大的改变了商业银行传统的经营模式。能够为客户提供方便、快捷、安全的服务,也能够有效的降低银行的营运成本,这是银行存储系统追求的目标。目前,对于现代化银行运营的要求是客户可以实现方便安全的业务交易,银行职员可以进行高效合理的工作管理,实现银行业务电子化。
系统开发的意义:方便用户快速的进行存款、取款、以及完成-些转账的交易,大大提高办公效率,能够及时、准确、有效的帮用户办理各种繁琐的手续,也减缓了银行工作人员的压力。

1. 目的与要求

1、目的:
(1)熟练掌握 C++语言的基本知识和技能:
(2)掌握面向对象程序设计的基本思想和方法;(3)能够利用所学的面向对象基本知识和技能,解决简单应用的程序设计
2、基本要求:(1)利用面向对象的方法以及 C++的编程思想来完成系统的设计;(2)在设计的过程中,建立清晰的类层次:定义各个类,每个类中要有各自的数据和成员函数:运用面向对象(继承、派生及多态性)来实现系统功能。
(3)在系统的设计中,要有清晰的界面设计,同时采用文件进行读写操作。
3、创新要求: 在基本要求达到后,可进行创新设计。

2. 问题描述及功能要求

设计一个银行账户管理程序,账户的信息有账号(唯一)、姓名、余额、身份证号码单位、电话号码、地址等,允许用户进行如下操作:开户、销户、存款、取款、转账、查询,一个用户可以有多个户头,账户的数值没有上限。程序运行时,可以由用户选择进行何种操作,开户操作要求输入用户信息后自动获取账号,用户销户后账号被回收,并且该账号可以继续分配给其它账户,不允许用户透支,根据姓名或账号可以进行用户的信息查询,所有的账户信息应存放到文件中,可以随时的访问和更新。
程序应输入不少于 10 人的账户信息,应考虑到人员同名的情况。

二、 实现思路以及代码

首先完成项目时,尽量不要定义全局变量。

1. Person

只能格式化的从文件中写入或读出数据,一个用户可以办多张银行卡,所以不能确定用户有几张卡,并且每张卡又有不同的余额,用一个Person类存人和卡的信息,每张卡都对应一个人(多对多),但是打印时可以将人的信息和卡的信息分开打印,这样处理容易实现其余功能,如果将人的信息和卡的信息用一对多的方法表示,那就必须再创建一个文件,对这个文件进行维护,非常麻烦,所以不建议一对多 代码如下:

//人和卡的信息
struct Person
{
	string _name; //姓名
	string _id; //身份证号码
	string _pnumber; //电话号码
	string _address; //地址
	string _account; //账号
	double _balance = 0.0; //余额
};

2. 创建账号

要求:用户销户后卡号被回收,并且该卡号可以继续分配给其它账户。
思路:用key-value来实现,key存账号,value存1或0(1表示未使用,0表示已使用)。必须先创建一个card.txt,向card.txt文件中写入账号,然后拿来使用,对这个card.txt文件进行维护就是对卡号进行维护,代码如下:

#define CARD "1000000000" //默认账号10位数
#define LENGTH 10
#define SIZE 1000 //默认写入1000个账号

void DataCreate()
{
	FILE* pf = fopen("card.txt", "w"); //打开文件
	if (pf == nullptr) //打开失败则返回
	{
		perror("fopen");
		return;
	}
	map<string, int> m;
	string s = CARD;
	int n = SIZE;
	while (n--)
	{
		m.insert(pair<string, int>(s, 1)); //插入map中
		fprintf(pf, "%s %d\n", s.c_str(), 1); //顺便打印到文件中
		int tmp = stoi(s);
		++tmp;
		s = to_string(tmp);
	}
}

编译后就可以在main.cpp文件路径下看到card.txt文件,并且卡号写入成功。
在这里插入图片描述

这个函数是向文件中写入账号的,所以先运行一次,得到card.txt之后就不需要运行。

3. 保存数据并且排序

因为是用身份证号来读取银行卡号,所以当用户再次办理银行卡,就需要对v_bankcard进行排序;在查看之前需要排序,退出之前也需要排序。

//按照身份证号来排序
	void Sort()
	{
		for (int i = 0; i < v_person.size(); ++i)
		{
			for (int j = i; j < v_person.size() - 1; ++j)
			{
				if (v_person[j]._id > v_person[j + 1]._id)
				{
					swap(v_person[j], v_person[j + 1]);
				}
			}
		}
	}
//保存数据
void cardSave()
{
	FILE* pf = fopen("card.txt", "w");
	if (pf == nullptr)
	{
		perror("DataCreate fopen");
		return;
	}
	map<string, int>::iterator it = ::card.begin();
	while (it != ::card.end())
	{
		fprintf(pf, "%s %d\n", (*it).first.c_str(), (*it).second);
		++it;
	}
	fclose(pf);
}
void v_personSave()
{
	FILE* pf = fopen("person.txt", "w");
	if (pf == nullptr)
	{
		perror("DataCreate fopen");
		return;
	}
	for (int i = 0; i < ::v_person.size(); ++i)
	{
		fprintf(pf, "%s %s %s %s %s %.2lf\n", v_person[i]._name.c_str(), v_person[i]._id.c_str(), v_person[i]._pnumber.c_str(), v_person[i]._address.c_str(), v_person[i]._account.c_str(), v_person[i]._balance);
	}
	fclose(pf);
}
void Save()
{
	cardSave();
	v_personSave();
}

上述函数搭配起来,再在主函数插入,就可以实现如下效果:
在这里插入图片描述

4. 查看所有人的银行卡信息

这个函数主要用来检验程序是否正确,数据是否输入正确,打印时,如果身份证号相同,则只打印一遍人的信息,代码如下:

	void Show()
	{
		int i = 0;
		while (i < v_person.size())
		{
			if ((i > 0) && (v_person[i]._id == v_person[i - 1]._id))
			{
				cout << v_person[i]._account << "  " << v_person[i]._balance << endl;
			}
			else
			{
				cout << v_person[i]._name << "  " << v_person[i]._id << "  " << v_person[i]._pnumber << "  " << v_person[i]._address << endl;
				cout << v_person[i]._account << "  " << v_person[i]._balance << endl;
			}
			++i;
		}
	}

效果如下:
在这里插入图片描述

5. 销户(注销银行卡)

销户有两种方法,一种是搜账号进行销毁,另一种是搜姓名进行销毁 (单姓名单卡号直接删,多姓名转换为按账号搜进行销毁) , 销户后将card中数据唤醒(即赋1),以便给其他用户使用。

  1. 按银行卡号删除
    按银行卡号删除就进行遍历v_person,然后进行删除,删除之前需释放卡号(即将card.second = 1)
  2. 按姓名删除
    按姓名删除void DestoryN(int n)需要传姓名的个数,int FindN()返回姓名的个数 (注意这里是多对多),只有当n==1时,才能直接删,否则按银行卡删。
	//通过银行卡号查找
	vector<Person>::iterator FindA(const string& account)
	{
		vector<Person>::iterator it = v_person.begin();
		while (it != v_person.end())
		{
			if ((*it)._account == account)
			{
				return it;
			}
			++it;
		}
		return it;
	}
	void Erase(vector<Person>::iterator& it)
	{
		map<string, int>::iterator itmap = card.begin();
		//将card.second赋值为1
		while (itmap != card.end())
		{
			if ((*itmap).first == (*it)._account)
			{
				(*itmap).second = 1;
				break;
			}
			++itmap;
		}
		//删除
		v_person.erase(it);
		cout << "删除成功" << endl;
	}
	//通过姓名删除
	void DestoryN(int n) 
	{
		if (n == 1) //没有重名
		{
			cout << "请再次输入要删除账户的姓名>:";
			string name;
			cin >> name;
			vector<Person>::iterator it = v_person.begin();
			while (it != v_person.end())
			{
				if ((*it)._name == name)
				{
					Erase(it);
					break;
				}
				++it;
			}
		}
		else //有重名或一个人有多张卡
		{
			cout << "有相同的姓名或多张银行卡" << endl;
			DestoryA();
		}
	}
	//通过银行卡号删除
	void DestoryA()
	{
		string account;
		cout << "请输入要删除的账号>:";
		cin >> account;
		vector<Person>::iterator it = FindA(account);
		Erase(it);
	}
	//查找姓名
	int FindName() 
	{
		int n = 0;
		while (true)
		{
			cout << "请输入要查找的姓名>:";
			string name;
			int i = 0;
			cin >> name;
			while (i < v_person.size())
			{
				if (v_person[i]._name == name)
				{
					cout << v_person[i]._name << "  " << v_person[i]._id << "  " << v_person[i]._pnumber << "  " << v_person[i]._address << "  " << v_person[i]._account << "  " << v_person[i]._balance << endl;
					++n;
				}
				++i;
			}
			if (n == 0)
				cout << "找不到,请重新输入!" << endl;
			else
				break;
		}

		return n;
	}
	//销户
	void CloseAccount()
	{
		int n = 0;
		int input = 0;
		do
		{
			cout << "请选择搜索销户的方式>:0.退出销毁  1.姓名  2.银行卡号" << endl;
			cout << "请选择>:";
			cin >> input;
			switch (input)
			{
			case 0:
				break;
			case 1:
				n = FindName();
				DestoryN(n);
				break;
			case 2:
				DestoryA();
				break;
			default:
				cout << "选择错误,请重新选择!" << endl;
				break;
			}
		} while (input);
	}

6. 存款、取款、转账

这些功能实现较简单,在v_person中遍历修改即可,代码如下:

	//存款
	void Deposit()
	{
		string account;
		cout << "请输入要存款的银行卡号>:";
		cin >> account;
		vector<Person>::iterator it = FindA(account);

		double balance = 0.0;
		cout << "请输入要存款的金额>:";
		cin >> balance;

		(*it)._balance += balance;
		cout << "存款成功" << endl;
	}
	//取款
	void Withdrawal()
	{
		string account;
		cout << "请输入要取的银行卡号>:";
		cin >> account;
		vector<Person>::iterator it = FindA(account);

		double balance = 0.0;
		cout << "请输入要取款的金额>:";
		cin >> balance;
		if ((*it)._balance < balance)
		{
			cout << "余额不足,取款失败! 余额为:" << (*it)._balance << endl;
		}
		else
		{
			(*it)._balance -= balance;
			cout << "取款成功! 剩余余额为:" << (*it)._balance << endl;
		}
	}
	//转账
	void Transfer()
	{
		double d;
		string a1;
		string a2;
		cout << "请输入被转的银行卡号:";
		cin >> a1;
		cout << "请输入转入的银行卡号:";
		cin >> a2;
		vector<Person>::iterator it1 = FindA(a1); 
		vector<Person>::iterator it2 = FindA(a2);
		cout << "请输入要转的金额>:";
		cin >> d;
		if ((*it1)._balance < d)
		{
			cout << "余额不足,转账失败! 余额为:" << (*it1)._balance << endl;
		}
		else
		{
			(*it1)._balance -= d;
			(*it2)._balance += d;
			cout << "转账成功!两张卡的余额分别为:" << (*it1)._balance << "  " << (*it2)._balance << endl;
		}
	}

三、 完整代码如下

银行管理系统大致思路如上,一些小细节就省略了。当然有些地方还需要一定的改善,比如可以加个办卡时间,还有好多地方需要二级菜单。
将上述一些代码放在Account类中,就可以跑起来

BAMSystem.h文件

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <algorithm> //sort
using namespace std;

#define CARD "1000000000" //默认银行卡号10位数
#define LENGTH 10 //银行卡号的长度
#define SIZE 1000 //默认写入1000个银行卡号
#define MAX 30

//人和卡的信息
struct Person
{
	string _name; //姓名
	string _id; //身份证号码
	string _pnumber; //电话号码
	string _address; //地址
	string _account; //账号
	double _balance = 0.0; //余额
};


//账户类
class Account
{
public:
	//初始化
	void cardInit()
	{
		FILE* pf = fopen("card.txt", "r");
		if (pf == nullptr)
		{
			perror("DataInit fopen");
			return;
		}
		pair<string, int> tmp;
		char s[LENGTH + 1];
		int n = 0;
		while (fscanf(pf, "%s %d", s, &n) != EOF)
		{
			s[LENGTH] = '\0';
			tmp.first = s;
			tmp.second = n;
			card.insert(tmp);
		}
		fclose(pf);
	}
	void v_personInit()
	{
		FILE* pf = fopen("person.txt", "r");
		if (pf == nullptr)
		{
			perror("v_personInit fopen");
			return;
		}
		char name[MAX]; char id[MAX]; char pnumber[MAX]; char address[MAX]; char account[MAX]; double balance = 0.0;
		while (fscanf(pf, "%s %s %s %s %s %lf", name, id, pnumber, address, account, &balance) != EOF)
		{
			name[MAX - 1] = '\0';     p._name = name;
			id[MAX - 1] = '\0';       p._id = id;
			pnumber[MAX - 1] = '\0';  p._pnumber = pnumber;
			address[MAX - 1] = '\0';  p._address = address;
			account[MAX - 1] = '\0';     p._account = account;
			p._balance = balance;
			v_person.push_back(p);
		}
		fclose(pf);
	}
	//按照身份证号来排序(排序可以更好的查看信息)
	void Sort()
	{
		for (int i = 0; i < v_person.size(); ++i)
		{
			for (int j = i; j < v_person.size() - 1; ++j)
			{
				if (v_person[j]._id > v_person[j + 1]._id)
				{
					swap(v_person[j], v_person[j + 1]);
				}
			}
		}
	}
	//保存数据
	void Save()
	{
		cardSave();
		v_personSave();
	}
	// 开户
	void OpenAccount()
	{
		//输入数据
		cout << "请输入姓名>:";
		cin >> p._name;
		cout << "请输入身份证号码>:";
		cin >> p._id;
		cout << "请输入电话号码>:";
		cin >> p._pnumber;
		cout << "请输入地址>:";
		cin >> p._address;

		//生成账号
		int n = 1;
		map<string, int>::iterator it = card.begin();
		while (it != card.end())
		{
			if ((*it).second == 1)
			{
				n = 0;
				p._account = (*it).first;
				(*it).second = 0; //使用后的卡号赋值为0
				break;
			}
			++it;
		}
		if (n)
			cout << "办理失败,请及时扩充银行卡号!" << endl;
		else
		{
			v_person.push_back(p);
			cout << "办理成功,银行卡号为:" << p._account << endl;
		}
	}
	//销户
	void CloseAccount()
	{
		int n = 0;
		int input = 0;
		do
		{
			cout << "请选择搜索销户的方式>:0.退出销毁  1.姓名  2.银行卡号" << endl;
			cout << "请选择>:";
			cin >> input;
			switch (input)
			{
			case 0:
				break;
			case 1:
				n = FindName();
				DestoryN(n);
				break;
			case 2:
				DestoryA();
				break;
			default:
				cout << "选择错误,请重新选择!" << endl;
				break;
			}
		} while (input);
	}
	//存款
	void Deposit()
	{
		string account;
		cout << "请输入要存款的银行卡号>:";
		cin >> account;
		vector<Person>::iterator it = FindA(account);

		double balance = 0.0;
		cout << "请输入要存款的金额>:";
		cin >> balance;

		(*it)._balance += balance;
		cout << "存款成功,余额为:" << (*it)._balance << endl;
	}
	//取款
	void Withdrawal()
	{
		string account;
		cout << "请输入要取的银行卡号>:";
		cin >> account;
		vector<Person>::iterator it = FindA(account);

		double balance = 0.0;
		cout << "请输入要取款的金额>:";
		cin >> balance;
		if ((*it)._balance < balance)
		{
			cout << "余额不足,取款失败! 余额为:" << (*it)._balance << endl;
		}
		else
		{
			(*it)._balance -= balance;
			cout << "取款成功! 剩余余额为:" << (*it)._balance << endl;
		}
	}
	//转账
	void Transfer()
	{
		double d;
		string a1;
		string a2;
		cout << "请输入被转的银行卡号:";
		cin >> a1;
		cout << "请输入转入的银行卡号:";
		cin >> a2;
		vector<Person>::iterator it1 = FindA(a1); 
		vector<Person>::iterator it2 = FindA(a2);
		cout << "请输入要转的金额>:";
		cin >> d;
		if ((*it1)._balance < d)
		{
			cout << "余额不足,转账失败! 余额为:" << (*it1)._balance << endl;
		}
		else
		{
			(*it1)._balance -= d;
			(*it2)._balance += d;
			cout << "转账成功!两张卡的余额分别为:" << (*it1)._balance << "  " << (*it2)._balance << endl;
		}
	}

	//查找姓名
	int FindName() 
	{
		int n = 0;
		while (true)
		{
			cout << "请输入要查找的姓名>:";
			string name;
			int i = 0;
			cin >> name;
			while (i < v_person.size())
			{
				if (v_person[i]._name == name)
				{
					cout << v_person[i]._name << "  " << v_person[i]._id << "  " << v_person[i]._pnumber << "  " << v_person[i]._address << "  " << v_person[i]._account << "  " << v_person[i]._balance << endl;
					++n;
				}
				++i;
			}
			if (n == 0)
				cout << "找不到,请重新输入!" << endl;
			else
				break;
		}

		return n;
	}
	//7.查看
	void Show()
	{
		int i = 0;
		while (i < v_person.size())
		{
			if ((i > 0) && (v_person[i]._id == v_person[i - 1]._id))
			{
				cout << v_person[i]._account << "  " << v_person[i]._balance << endl;
			}
			else
			{
				cout << v_person[i]._name << "  " << v_person[i]._id << "  " << v_person[i]._pnumber << "  " << v_person[i]._address << endl;
				cout << v_person[i]._account << "  " << v_person[i]._balance << endl;
			}
			++i;
		}
	}
private:
	void Erase(vector<Person>::iterator& it)
	{
		map<string, int>::iterator itmap = card.begin();
		//将card.second赋值为1
		while (itmap != card.end())
		{
			if ((*itmap).first == (*it)._account)
			{
				(*itmap).second = 1;
				break;
			}
			++itmap;
		}
		//删除
		v_person.erase(it);
		cout << "删除成功" << endl;
	}
	//通过姓名删除
	void DestoryN(int n) 
	{
		if (n == 1) //没有重名
		{
			cout << "请再次输入要删除账户的姓名>:";
			string name;
			cin >> name;
			vector<Person>::iterator it = v_person.begin();
			while (it != v_person.end())
			{
				if ((*it)._name == name)
				{
					Erase(it);
					break;
				}
				++it;
			}
		}
		else //有重名或一个人有多张卡
		{
			cout << "有相同的姓名或多张银行卡" << endl;
			DestoryA();
		}
	}
	//通过银行卡号删除
	void DestoryA()
	{
		string account;
		cout << "请输入要删除的账号>:";
		cin >> account;
		vector<Person>::iterator it = FindA(account);
		Erase(it);
	}
	//通过银行卡号查找
	vector<Person>::iterator FindA(const string& account)
	{
		vector<Person>::iterator it = v_person.begin();
		while (it != v_person.end())
		{
			if ((*it)._account == account)
			{
				return it;
			}
			++it;
		}
		return it;
	}


	//保存数据
	void cardSave()
	{
		FILE* pf = fopen("card.txt", "w");
		if (pf == nullptr)
		{
			perror("DataCreate fopen");
			return;
		}
		map<string, int>::iterator it = card.begin();
		while (it != card.end())
		{
			fprintf(pf, "%s %d\n", (*it).first.c_str(), (*it).second);
			++it;
		}
		fclose(pf);
	}
	void v_personSave()
	{
		FILE* pf = fopen("person.txt", "w");
		if (pf == nullptr)
		{
			perror("DataCreate fopen");
			return;
		}
		for (int i = 0; i < v_person.size(); ++i)
		{
			fprintf(pf, "%s %s %s %s %s %.2lf\n", v_person[i]._name.c_str(), v_person[i]._id.c_str(), v_person[i]._pnumber.c_str(), v_person[i]._address.c_str(), v_person[i]._account.c_str(), v_person[i]._balance);
		}
		fclose(pf);
	}
private:
	Person p;
	vector<Person> v_person; //用来存储人的数据
	map<string, int> card; //卡号是否使用
};
void menu()
{
	cout << "*******************************************" << endl;
	cout << "*******  1.开户  2.销户  3.存款  **********" << endl;
	cout << "*******  4.取款  5.转账  6.查询  **********" << endl;
	cout << "*******  7.查看    0.退出        **********" << endl;
	cout << "*******************************************" << endl;
}
int main()
{
	Account a;
	a.cardInit();
	a.v_personInit();
	int input = 0;
	do
	{
		menu();
		cout << "请选择>:";
		cin >> input;
		switch (input)
		{
		case 0:
			a.Sort(); //先排序,在保存
			a.Save();
			cout << "退出程序" << endl;
			break;
		case 1:
			a.OpenAccount();
			break;
		case 2:
			a.CloseAccount();
			break;
		case 3:
			a.Deposit();
			break;
		case 4:
			a.Withdrawal();
			break;
		case 5:
			a.Transfer();
			break;
		case 6:
			a.FindName();
			break;
		case 7:
			a.Show();
			break;
		default:
			cout << "选择错误,请重新选择。" << endl;
			break;
		}

	} while (input);
	return 0;
}

//只用来生成card.txt文件,生成card.txt文件后就不在使用,除非修改银行卡号的位数
//void DataCreate()
//{
//	FILE* pf = fopen("card.txt", "w");
//	if (pf == nullptr)
//	{
//		perror("DataCreate fopen");
//		return;
//	}
//	map<string, int> m;
//	string s = CARD;
//	int n = SIZE;
//	while (n--)
//	{
//		m.insert(pair<string, int>(s, 1));
//		fprintf(pf, "%s %d\n", s.c_str(), 1);
//		int tmp = stoi(s);
//		++tmp;
//		s = to_string(tmp);
//	}
//	fclose(pf);
//}

下图为删除银行卡号效果:
在这里插入图片描述
card.txt文件中:
在这里插入图片描述
person.txt文件中:
在这里插入图片描述

当然实际上银行管理系统远比上述复杂的多,好多地方都需要改进,而上述代码仅将一些功能实现,真正的银行卡系统当然还有密码,销户时还有余额该怎么搞,以及管理员登录和普通用户登录等等一些问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ly@눈_눈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值