程序要求
结构图
源码
由于我平时上课不听讲,数据结构没搞懂,导致代码中文件保存和用户结构部分都是copy站内大佬的代码,在此我表示感谢
另外,由于我没有定义消费的结构体,导致无法查询消费记录,等我学会这块了会重新完善此系统,也希望有大佬可以教教我咋搞,感谢
Bank.h
#ifndef BANK_H_INCLUDED
#define BANK_H_INCLUDED
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define upNum 2000 //系统最多容纳的用户数
struct record
{
int account; //账号
int password; //密码
char name[10]; //用户名
double balance; //账户余额
int status; //状态
};
struct record users[upNum]; //银行所有用户
int N; //实际的用户数目
void pass(); //用户登录
void adminpass(); //管理员登录
void readData(); //开始前从文件中读数据,存在数组中
void writeData(); //程序结束前,将数组中的数据写入到文件中
int chooseInMenu(); //显示菜单并由业务员选择
void openAccount(); //开户
void save(); //存款
void Menu(); //用户菜单
void withdraw(); //取款
void showAccount(); //查询用户信息
void showAll(); //显示所有用户
void showBalance(); //查询余额
void findData(); //查询消费记录(没做出来)
void freeze(); //冻结
void cancelfreeze(); //解除冻结
int inputPassword(); //返回键盘输入的密码
int search(int); //根据账号找到用户数据对应的下标
int welcomeMenu();//登录界面
int ichooseInMenu();//用户菜单
int adminchooseMenu();//管理员菜单
void adminMenu();//管理员菜单
void welcome();//欢迎界面功能
#endif // BANK_H_INCLUDED
此处为头文件,所有函数,变量的定义都放在这里,每行后都有注释,我就不多说了
interface.c
#include "Bank.h"
/*登录界面*/
int welcomeMenu()
{
int i;
while(1)
{
printf("+------------------------------+\n");
printf("+ +\n");
printf("+ 欢迎使用银行管理系统 +\n");
printf("+ +\n");
printf("+ 1 开户 2 登录 3 管理员登录+\n");
printf("+ 0 退出系统 +\n");
printf("+------------------------------+\n");
printf("请选择: ");
fflush(stdin);
scanf("%d",&i);
if(i>=0 &&i<=3)
break;
else
printf("输入有误,请重新选择\n\n");
}
return i;
}
/*用户菜单*/
int ichooseInMenu()
{
int i;
while(1)
{
printf("\n");
printf("+--------------+\n");
printf("| 1 查询余额 |\n");
printf("| 2 记录查询 |\n");
printf("| 3 存钱 |\n");
printf("| 4 取钱 |\n");
printf("| 0 退出 |\n");
printf("+--------------+\n");
printf("请输入您的选择: ");
scanf("%d",&i);
if(i>=0 &&i<=4)
break;
else
printf("输入有误,请重新选择\n\n");
}
return i;
}
/*管理员菜单*/
int adminchooseMenu()
{
int i;
while(1)
{
printf("\n");
printf("+-------------------+\n");
printf("| 1 查询余额 |\n");
printf("| 2 记录查询 |\n");
printf("| 3 存钱 |\n");
printf("| 4 取钱 |\n");
printf("| 5 查看所有账户 |\n");
printf("| 6 查询账户信息 |\n");
printf("| 7 冻结账户 |\n");
printf("| 8 解冻账户 |\n");
printf("| 0 退出 |\n");
printf("+-------------------+\n");
printf("请输入您的选择: ");
scanf("%d",&i);
if(i>=0 &&i<=8)
break;
else
printf("输入有误,请重新选择!\n\n");
}
return i;
}
这里是所有用户界面,有注释,也没啥说的
function.c
#include "bank.h"
/*欢迎界面功能*/
void welcome()
{
int Choice;/*用户选择功能*/
do
{
Choice=welcomeMenu();
switch(Choice)
{
case 1:
openAccount();/*开户*/
break;
case 2:
pass();/*用户登录*/
break;
case 3:
adminpass();/*管理员登录*/
break;
case 0:
printf("欢迎您再来. \n");
}
}
while(Choice);
}
/*开户*/
void openAccount()
{
if(N==upNum)
{
printf("银行用户数已经达到上限,不能再开户");
return;
}
//下面正常办理开户业务
printf("正在开户\n");
users[N].account=10001+N;
printf("账号:%d", users[N].account);
printf("户主姓名:");
scanf("%s", users[N].name);
int iPass1, iPass2;
printf("密码:");
iPass1=inputPassword(); //输入密码1
printf("确认密码:");
iPass2=inputPassword(); //输入密码2
if(iPass1==iPass2)
{
users[N].password=iPass1;
users[N].status=0; //账户状态为“正常”
printf("存入金额:");
scanf("%lf", &users[N].balance);
N++; //正式用户数增加1,确认了新用户已经加入
printf("成功开户!\n");
}
else
{
printf("两次密码不一致,未成功开户!\n"); //没有N++,则读入的值无效
}
}
/*用户登录*/
void pass()
{
int id; //用于输入的账号
int who; //查找到该账号在数组中对应的下标
int sPass; //业务员登录时输入的密码
int right = 0; //要返回的结果:0-不正确 1-正确
printf("请输入账号:");
scanf("%d", &id);
who = search(id); //根据账号查询用户,返回用户的下标
if(who<0) //说明id账户不存在
{
printf("该用户不存在,登录失败!\n");
}
else
{
printf("请输入密码:");
sPass=inputPassword();
if(sPass==users[who].password)
{
right = 1;
}
else
{
printf("对不起,密码错误\n");
}
if (right==1)
Menu();
else
return;
}
}
/*管理员登录*/
void adminpass()
{
char userName[7];
char userPWD[7];
int i;
for(i=0; i<3; i++)
{
printf("\n");
printf("请输入用户名:");
scanf("%s", userName);
fflush(stdin);
printf("\n请输入您的密码:");
scanf("%s", userPWD);
fflush(stdin);
if ((strcmp(userName,"admin")==0) && (strcmp(userPWD,"admin")==0))
{
//用户名和密码正确,显示管理员菜单
adminMenu();
return;
}
else
{
if (i < 2)
{
//用户名或密码错误,提示用户重新输入
printf("用户名或密码错误,请重新输入!\n");
}
else
{
//连续3次输错用户名或密码,退出系统。
printf("用户名或密码错误,退出系统!\n");
}
}
}
}
/*用户菜单*/
void Menu()
{
int iChoice;/*用户选择功能*/
do
{
iChoice=ichooseInMenu();
switch(iChoice)
{
case 1:
showBalance();/*查询余额*/
break;
case 2:
findData();/*查询记录,还没做好*/
break;
case 3:
save();/*存钱*/
break;
case 4:
withdraw();/*取钱*/
break;
case 0:
printf("欢迎您再来. \n");
break;
}
}
while(iChoice);
}
/*管理员菜单*/
void adminMenu()
{
int Choice;/*用户选择功能*/
do
{
Choice=adminchooseMenu();
switch(Choice)
{
case 1:
showBalance();//查询余额
break;
case 2:
findData();//查询记录,还没做好
break;
case 3:
save();//存钱
break;
case 4:
withdraw();//取钱
break;
case 5:
showAll();//查询所有账户
break;
case 6:
showAccount();//查询账户信息
break;
case 7:
freeze();//冻结
break;
case 8:
cancelfreeze();//解冻
break;
case 0:
printf("欢迎您再来. \n");
}
}
while(Choice);
}
/*存款*/
void save()
{
int id, who;
double money;
printf("输入要存款的账号:");
scanf("%d", &id);
who = search(id); //根据账号查询用户,返回用户的下标
if(who<0) //说明id账户不存在
{
printf("该用户不存在,存款失败!\n");
}
else
{
if(users[who].status==0)
{
printf("用户姓名:%s\n", users[who].name);
printf("输入存款额:");
scanf("%lf", &money);
users[who].balance+=money;
printf("存款后,您有%.2f元. \n",users[who].balance);
}
else if(users[who].status==1)
{
printf("该用户处于冻结状态,存款失败!\n");
}
}
return;
}
/*取款*/
void withdraw()
{
int id, who;
int iPass;
double money;
printf("输入要取款的账号:");
scanf("%d", &id);
who = search(id); //根据账号查询用户,返回用户的下标
if(who<0) //说明id账户不存在
{
printf("该用户不存在,取款失败!\n");
}
else
{
if(users[who].status==0)
{
printf("用户姓名:%s\n", users[who].name);
printf("密码:");
iPass=inputPassword();
if(iPass!=users[who].password)
{
printf("输入密码错误,取款失败!\n");
}
else
{
printf("输入取款额:");
scanf("%lf", &money);
if(money>users[who].balance) //亲,不玩透支
{
printf("余额不足,取款失败!\n");
}
else
{
users[who].balance-=money;
printf("取款后,还有%.2f元. \n",users[who].balance);
}
}
}
else if(users[who].status==1)
{
printf("该用户处于冻结状态,取款失败!\n");
}
}
return;
}
/*余额查询*/
void showBalance()
{
int id, who;
printf("账号:");
scanf("%d", &id);
who = search(id); //根据账号查询用户,返回用户的下标
if(who<0) //说明id账户不存在
{
printf("该用户不存在!\n");
}
else
{
printf("用户姓名:%s\n", users[who].name);
{
printf("余额:%.2f元. \n",users[who].balance);
}
}
return;
}
/*查询账户*/
void showAccount()
{
int id, who;
printf("账号:");
scanf("%d", &id);
who = search(id); //根据账号查询用户,返回用户的下标
if(who<0) //说明id账户不存在
{
printf("该用户不存在!\n");
}
else
{
printf("户主姓名:%s\n", users[who].name);
{
printf("余额:%.2f元. \n",users[who].balance);
printf("状态:");
if(users[who].status==0)
{
printf("正常\n");
}
else if(users[who].status==1)
{
printf("冻结\n");
}
}
}
return;
}
/*查询记录还没做好*/
void findData()
{
return ;
}
/*显示所有账户*/
void showAll()
{
int i;
printf("账号 用户名 密码\n");
for(i=0;i<=N;i++)
{
printf("%d %s %d",users[i].account, users[i].name, users[i].password);
}
}
/*冻结账户*/
void freeze()
{
int id, who;
printf("账号:");
scanf("%d", &id);
who = search(id); //根据账号查询用户,返回用户的下标
if(who<0) //说明id账户不存在
{
printf("该用户不存在,无法冻结!\n");
}
else
{
printf("户主姓名:%s\n", users[who].name);
if(users[who].status==0)
{
users[who].status=1;
printf("挂失成功\n");
}
else if(users[who].status==1)
{
printf("该账户已经处于冻结状态\n");
}
}
return;
}
/*解除冻结*/
void cancelfreeze()
{
int id, who;
printf("账号:");
scanf("%d", &id);
who = search(id); //根据账号查询用户,返回用户的下标
if(who<0) //说明id账户不存在
{
printf("该用户不存在,解除冻结失败!\n");
}
else
{
printf("户主姓名:%s\n", users[who].name);
if(users[who].status==0)
{
printf("该账户处于正常状态,不需要解除冻结\n");
}
else if(users[who].status==1)
{
users[who].status=0;
printf("解除冻结成功\n");
}
}
return;
}
/*根据账号查询用户,返回用户的下标*/
int search(int id)
{
int index=-1;
int low=0, high=N-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;
}
return index; //若找到,其值在0~N-1间,否则,保持-1
}
/*读取文件内容*/
void readData()
{
FILE *fp; //用于文件操作
int i = 0;
//从文件中取出余额
if ((fp=fopen("account.txt", "a+"))==NULL)
{
printf("data file cannot open!");
exit(0);
}
while(fscanf(fp,"%d %s %d %lf %d",&users[i].account, users[i].name, &users[i].password, &users[i].balance,&users[i].status ) != EOF)
{
i++;
}
N = i; //用全局变量存储用户的总人数
fclose(fp);
return;
}
/*将数据保存到文件中*/
void writeData()
{
FILE *fp; //用于文件操作
int i=0;
//保存余额
if ((fp=fopen("account.txt", "w"))==NULL)
{
printf("data file cannot open!");
exit(0);
}
for(i=0; i<N; i++)
fprintf(fp,"%d %s %d %f %d\n",users[i].account, users[i].name, users[i].password, users[i].balance,users[i].status);
fclose(fp);
}
/*规范密码并将输入密码变成星号*/
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); //清除键盘缓存区中已经有的输入
printf("\n");
if(iPass==0) //此条件成立可能由两种情况引起:输入了非数字字符被直接重置为0,或6位全0后正常退出for循环
{
printf("密码要求全为数字,且不全为0!\n");
printf("请重新输入密码: ");
}
else
break;
}
return iPass;
}
所有函数都在这里,每个都有功能注释
管理员的账号密码都是:admin
也没啥需要特殊说明的。
最后是
main.c
#include "bank.h"
/*主函数:*/
int main()
{
system("title 银行管理系统");
readData();
welcome();
writeData();
return 0;
}
就是读取文件里的数据,进入程序,然后运算一番,最后把数据再写回去,这里我想说的是一开始文件的打开方式给我造成了很多麻烦,有时写不进去,有时读不出来,还有无法创建和每次都要重新注册的情况,我一直不知道哪出了问题,最后发现是文件打开方式的原因。
附上百度来的各种打开方式用法
r 以只读方式打开文件,该文件必须存在。
r+ 以可读写方式打开文件,该文件必须存在。
rb+ 读写打开一个二进制文件,允许读写数据,文件必须存在。
w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)
wb 只写打开或新建一个二进制文件;只允许写数据。
wb+ 读写打开或建立一个二进制文件,允许读和写。
ab+ 读写打开一个二进制文件,允许读或在文件末追加数据。
wx 创建文本文件,只允许写入数据.[C11]
wbx 创建一个二进制文件,只允许写入数据.[C11]
w+x 创建一个文本文件,允许读写.[C11]
wb+x 创建一个二进制文件,允许读写.[C11]
w+bx 和"wb+x"相同[C11]
我最后用了a+读取文件,w 修改文件,这样第一次开户时就可以自动创建文件,不需要手动操作,在最后将数据写入文件时先将文件中的旧数据进行清理,再将新的数据存放进到文件中。
放几张图吧
总结
一开始我真没想到会把问题搞得这么复杂,以为挺简单的小程序搞到最后一天早上6点才草草收尾,我的c语言基础太薄弱了,
一直以来也眼高手低,只想着把学校里的东西学会就行(也没学多少),自己上手试一试才知道里面蕴含的各种知识是学校里根本没有教过的,
不论结果如何,我从这次入门测试中收获了许多,也找到了前进的方向,希望我下次回来重新编写这个程序的时候,能无情的嘲笑现在的自己代码写的有多么烂
不多说了,好困,睡觉去了,各位早安