文件相關(guān)知識可參考:文件(點擊即可進入)
一段路大學(xué)學(xué)生專用銀行
本行所提供的的服務(wù)包括以下幾種:開戶、顯示、保存、登錄、退出 登錄成功后主要包括以下功能:存款、取款、查詢余額、修改密碼、轉(zhuǎn)賬、銷毀、返回
一、ATM.h 1、頭文件注:本程序的存儲方式為文件磁盤的存儲模式,采用數(shù)組的定義方式,未曾使用數(shù)據(jù)庫??!
#include#include#include#include#include
2、定義常量#define MAX_ID 10 //賬號
#define MAX_NAME 20 //姓名
#define MAX_SEX 5 //性別
#define MAX_DEP 30 //院系
#define MAX_MAJOR 30 //專業(yè)
#define MAX_CLASS 30 //班級
#define MAX_CARD 30 //卡號
#define MAX_PASSWORD 10 //密碼
#define MAX_BANK 30 //開戶行
#define MAX_MONEY 20000 //最高取款(轉(zhuǎn)賬)限度
3、賬戶信息本行賬戶所需信息主要包括:xh-賬號、xm-姓名、xb-性別、yx-院系、zy-專業(yè)、bj-班級、kh-卡號、khh-開戶行、khsj-開戶時間、ye-余額、zt-狀態(tài)、mm-初始密碼
注:賬戶信息命名規(guī)則:一律采用的拼音首字母小寫進行的變量命名
typedef struct ATM_ACCOUNT {char xh[MAX_ID], xm[MAX_NAME], xb[MAX_SEX], yx[MAX_DEP], zy[MAX_MAJOR],
bj[MAX_CLASS], kh[MAX_CARD], mm[MAX_PASSWORD], khh[MAX_BANK];
char zt;//銀行卡狀態(tài)
long khsj;//開戶時間
float ye;//余額
}ATM_account;
4、函數(shù)聲明//初始化相關(guān)函數(shù)
void init();//初始化函數(shù)
int getNum();//獲取本機所有賬戶函數(shù)
//初始界面相關(guān)函數(shù)
void menu1();//初始界面菜單函數(shù)
void welcome();//初始界面選擇功能函數(shù)
void Open_account();//開戶函數(shù)
void Show_account();//顯示賬戶信息函數(shù)
void Login();//登錄函數(shù)
void Save_account();//保存函數(shù)
//主界面相關(guān)函數(shù)
void menu2();//主機菜單函數(shù)
void mainmenu();//主機菜單選擇功能函數(shù)
void Money();//存取款金額選擇函數(shù)
void Deposit();//存款函數(shù)
void Money_Slove1();//固定存款金額處理函數(shù)
void Other_Money1();//任意存款金額處理函數(shù)
void Draw();//取款函數(shù)
void Money_Slove2();//取款金額選擇功能函數(shù)
void Sub_Money(int k);//固定金額取款處理函數(shù)
void Other_Money2();//任意金額取款處理函數(shù)
void Query();//查詢余額函數(shù)
void ChangePwd();//修改密碼函數(shù)
void Transfer();//轉(zhuǎn)賬函數(shù)
int validata_ID(char* p);//轉(zhuǎn)賬賬戶核對函數(shù)
int validata_Money(int money);//轉(zhuǎn)賬金額合法性檢查函數(shù)
二、Main_ATM
1、初始界面菜單void menu1() {puts("**********************************************");
puts("*1.開戶 2.顯示賬戶 3.登錄 4.存盤 0.退出*");
puts("**********************************************");
printf("請選擇:>");
}
2、初始界面選擇器void welcome() {int input = 0;
while (1) {system("cls");
menu1();
scanf("%d", &input);
switch (input) {case 1:Open_account(); break;
case 2:Show_account(); break;
case 3:Login(); break;
case 4:Save_account(); break;
case 0://退出之前要自動保存一下信息
Save_account(); puts("歡迎下次使用!"); system("pause"); exit(0);
default:puts("選擇錯誤,請重試!"); system("pause"); break;
}
}
}
3、主函數(shù)int main() {init();//初始化
welcome();//歡迎界面
return 0;
}
三、Fun_ATM
定義幾個全局變量int max_account,//賬戶的上限值,存在一個文本文件中
cnt_account,//現(xiàn)有賬戶數(shù),存在一個二進制文件中
sign;//登錄賬戶的角標
ATM_account atm_account;
ATM_account* p_account = &atm_account;//指向的內(nèi)存塊,存放具體的賬戶信息
(一)初始化相關(guān)函數(shù)1、獲取本地已有數(shù)據(jù)注:開始前需在文件存儲位置處,建立一個data文件夾,里面建立一個init.txt的文件,init.txt 文件里面存入max_account=100;,記錄賬戶的上限
int getNum() {FILE* fp;
int i = 0;
long pos = 0;
if ((fp = fopen("data\\atm_account.dat", "rb")) == NULL) {perror("getNum_atm_account.dat"); system("pause"); return 0;
}
fseek(fp, 0, SEEK_END);//定位文件函數(shù)
pos = ftell(fp);//pos---->文件的尺寸?。。?!
if (pos == -1) {puts("文件定位出錯!"); system("pause");
return 0;
}
return pos / sizeof(ATM_account);//結(jié)果就是atm_account.dat存放了多少個賬戶的信息?。?!
fclose(fp);
fp = NULL;
}
2、初始化void init() {FILE* fp;
int i = 0;
cnt_account = getNum();//獲取本機現(xiàn)有賬戶數(shù)
if ((fp = fopen("data\\init.txt", "r")) == NULL) {perror("init_init.txt"); system("pause"); return;
}
fscanf(fp, "max_account=%d;", &max_account);
printf("max_account = %d\n", max_account);
if (max_account<= 0) {puts("初始化數(shù)據(jù)有誤,程序終止執(zhí)行!"); system("pause"); return;
}
//內(nèi)存分配!
p_account = (ATM_account*)malloc(max_account * sizeof(ATM_account));
if (p_account == NULL) {puts("內(nèi)存分配失敗,程序終止執(zhí)行!"); system("pause"); return;
}
fclose(fp);
if ((fp = fopen("data\\atm_account.dat", "rb")) == NULL) {perror("init_atm_account.dat"); system("pause"); return;
}
fread(&cnt_account, sizeof(int), cnt_account, fp);
fread(p_account, sizeof(ATM_account), cnt_account, fp);
printf("共有%d個賬戶信息!\n", cnt_account);
puts("初始化完畢!");
system("pause");
fclose(fp);
fp = NULL;
}
(二)初始界面相關(guān)函數(shù)
1、開戶void Open_account() {printf("賬號:>"); scanf("%s", p_account[cnt_account].xh);
printf("姓名:>"); scanf("%s", p_account[cnt_account].xm);
printf("性別:>"); scanf("%s", p_account[cnt_account].xb);
printf("院系:>"); scanf("%s", p_account[cnt_account].yx);
printf("專業(yè):>"); scanf("%s", p_account[cnt_account].zy);
printf("班級:>"); scanf("%s", p_account[cnt_account].bj);
printf("卡號:>"); scanf("%s", p_account[cnt_account].kh);
printf("開戶行:>"); scanf("%s", p_account[cnt_account].khh);
p_account[cnt_account].khsj = time(0);
p_account[cnt_account].ye = 0.0f;
p_account[cnt_account].zt = '0';//賬戶狀態(tài)良好為'0'
strcpy(p_account[cnt_account].mm, "000000");
cnt_account++;//開戶數(shù)增加1
puts("開戶完畢!"); system("pause");
}
2、顯示賬戶信息void Show_account() {int i = 0;
if (cnt_account == 0)
puts("還未有人開戶,NO.1快去開戶吧!");
else {while (i< cnt_account) { printf("%s\t%5s\t%5s\t%15s\t%15s\t%10s\t%10s\t%5s\t%5c\t%15s\t%15ld\t%10.2f\t\n",
p_account[i].xh, p_account[i].xm, p_account[i].xb,
p_account[i].yx, p_account[i].zy, p_account[i].bj,
p_account[i].kh, p_account[i].mm, p_account[i].zt,
p_account[i].khh, p_account[i].khsj, p_account[i].ye);
i++;
}
}
puts("顯示完畢!"); system("pause");
}
3、登錄注:此處若是三次登錄都失敗,可將賬戶鎖定,鎖定就將狀態(tài)改為 ‘1’
void Login() {int times = 0, i = 0;
int flag = 0;
char xh[MAX_ID], mm[MAX_PASSWORD];
do {system("cls");
puts("歡迎使用農(nóng)業(yè)銀行ATM機");
printf("賬號:>"); scanf("%s", xh);
printf("密碼:>"); scanf("%s", mm);
//到p_account所指的內(nèi)存中查找該賬號和密碼;
//如果比對上,則進入主操作界面(mainmenu());
//否則,重新輸入賬號、密碼,循環(huán),直到用完3次機會!
for (i = 0; i< cnt_account; i++)
if (strcmp(xh, p_account[i].xh) == 0 && strcmp(mm, p_account[i].mm) == 0) { sign = i;//記錄當前登錄的賬戶角標
flag = 1; break;
}
if (flag == 1) break;
else { puts("賬戶或密碼錯誤,請重試!");
system("pause");
}
times++;
} while (times< 3);
if (times == 3) {//鎖定——狀態(tài)改為1
//strcpy(p_account[sign].zt,'1');//鎖定賬戶
//puts("三次登錄失敗,賬戶已被鎖定!");
puts("三次登錄失敗!");
system("pause");
}
if (flag == 1) {puts("登錄成功!");
system("pause");
mainmenu();
}
}
4、存盤void Save_account() {FILE* fp;
int i = 0;
if ((fp = fopen("data\\atm_account.dat", "wb")) == NULL) {perror("Save_account_atm_account.dat"); system("pause"); return;
}
fwrite(&cnt_account, sizeof(cnt_account), cnt_account, fp);//先寫賬戶總數(shù)
i = fwrite(p_account, sizeof(ATM_account), cnt_account, fp);//再寫具體的賬戶信息
if (i == 0)
puts("存盤失敗!");
else {printf("保存完畢,共存入%d個賬戶信息!\n", i);
}
system("pause");
fclose(fp);
fp = NULL;
}
(三)主界面相關(guān)函數(shù)
主界面選擇系統(tǒng)
a、主界面菜單void menu2() {puts("**************************************************");
puts("*** 1、存款 2、取款 3、查詢余額 4、修改密碼 ***");
puts("*** 5、轉(zhuǎn)賬 6、銷戶 0、返回 ***");
puts("**************************************************");
printf("請選擇:>");
}
b、主界面選擇器void mainmenu() {int input = 0;
while (1) {system("cls");
menu2();
scanf("%d", &input);
switch (input) {case 1:Deposit(); break;
case 2:Draw(); break;//待完成項目
case 3:Query(); break;
case 4:ChangePwd(); break;
case 5:Transfer(); break;
case 6:Logout();
case 0:welcome(); break;
default:puts("選擇有誤,請重試!"); system("pause"); break;
}
}
}
1、存款存款金額:只能存入百元大鈔(即:大于100且為100的整數(shù)倍)
void Deposit() {Money_Slove1();
printf("%s的余額為:%.2f\n", p_account[sign].xh, p_account[sign].ye);
puts("存款完畢!"); system("pause");
}
a、存取款金額選擇菜單void Money() {puts("****************************************************");
puts("*** 1、100元 ** 2、200元 ** 3、500元 ***");
puts("*** 4、1000元 ** 5、2000元 ** 6、其他金額 ***");
puts("******************** 0、返回 ***********************");
puts("****************************************************");
printf("請選擇:>");
}
b、處理存款金額void Money_Slove1() {int input = 0;
while (1) {system("cls");
Money();
scanf("%d", &input);
switch (input) {case 1:p_account[sign].ye += 100;
puts("已存入100元"); system("pause"); break;
case 2:p_account[sign].ye += 200;
puts("已存入200元"); system("pause"); break;
case 3:p_account[sign].ye += 500;
puts("已存入500元"); system("pause"); break;
case 4:p_account[sign].ye += 1000;
puts("已存入1000元"); system("pause"); break;
case 5:p_account[sign].ye += 2000;
puts("已存入2000元"); system("pause"); break;
case 6:Other_Money1(); break;
case 0:return;
default:puts("選擇有誤,請重試!"); system("pause"); break;
}
}
}
void Other_Money1() {//處理其他金額的情況
int money = 0;
puts("本行僅支持存入百元大鈔!");
printf("請輸入存款金額:>"); scanf("%d", &money);
//判斷存入金額是否為百元大鈔
if (money >= 100 && money % 100 == 0) {//是
p_account[sign].ye += money;
printf("已存入%d元\n", money);
}
else {//否
puts("存入金額不符要求,無法存入!");
}
system("pause");
}
2、取款取款金額條件:非負、余額充足、小于單筆上限、整取
void Draw() {printf("%s的余額為:%.2f\n", p_account[sign].xh, p_account[sign].ye);
Money_Slove2();//取款
printf("%s的余額為:%.2f\n", p_account[sign].xh, p_account[sign].ye);
puts("取款完畢!"); system("pause");
}
處理取款金額void Money_Slove2() {int input = 0;
int k = 0;
while (1) {system("cls");
Money();
scanf("%d", &input);
switch (input) {case 1:k = 100; Sub_Money(k); break;
case 2:k = 200; Sub_Money(k); break;
case 3:k = 500; Sub_Money(k); break;
case 4:k = 1000; Sub_Money(k); break;
case 5:k = 2000; Sub_Money(k); break;
case 6:Other_Money2(); break;
case 0:return;
default:puts("選擇有誤,請重試!"); system("pause"); break;
}
}
}
void Sub_Money(int k) {//處理余額不足的情況
if (k >p_account[sign].ye)
puts("余額不足,取款失敗!");
else {p_account[sign].ye -= k;
printf("已取走%d元\n", k);
}
system("pause");
}
void Other_Money2() {//處理其他金額的情況
int money = 0;
puts("本行僅支持按50的倍數(shù)取款!");
printf("請輸入取款金額:>"); scanf("%d", &money);
//判斷取款金額:非負、小于余額、50的倍數(shù)、上限
if (money >= 0 && money<= p_account[sign].ye && money % 50 == 0 && money<= MAX_MONEY) {//是
p_account[sign].ye -= money;
printf("已取走%d元\n", money);
}
else {//否
puts("取款金額不符要求,無法取款!");
}
system("pause");
}
3、查詢余額void Query() {printf("%s的余額為:%.2f\n", p_account[sign].xh, p_account[sign].ye);
system("pause");
}
4、轉(zhuǎn)賬輸入對方賬號:1、是否存在,2、賬戶狀態(tài),3、不能轉(zhuǎn)給自己
輸入轉(zhuǎn)賬金額:1、非負數(shù),2、50的倍數(shù),3、上限
轉(zhuǎn)賬:1、修改自己的余額,2、修改對方的余額 記錄交易信息:1、自己轉(zhuǎn)出的,2、對方的轉(zhuǎn)入的(此功能未實現(xiàn))
void Transfer() {char reci_xh[MAX_ID];
int trans_sign;//轉(zhuǎn)賬的賬號角標
again3:
system("cls");
printf("請輸入需要轉(zhuǎn)賬的賬號:>"); scanf("%s", reci_xh);
//判斷賬號合法性
trans_sign = validata_ID(reci_xh);
if (trans_sign >= 0) {//合法
int tra_amount = 0;
printf("請輸入轉(zhuǎn)賬金額:>"); scanf("%d", &tra_amount);
if (validata_Money(tra_amount) >0) {//合法
p_account[sign].ye -= tra_amount; p_account[trans_sign].ye += tra_amount;
printf("轉(zhuǎn)賬成功,共計轉(zhuǎn)賬%d元!", tra_amount); system("pause");
}
else { puts("金額不足,無法轉(zhuǎn)賬!"); system("pause");
}
}
else {//非法
int a = 0;
puts("賬號有誤,重試請按——1 !");
a = _getch();
if (a == 1) { goto again3;
}
else { puts("已取消轉(zhuǎn)賬!"); system("pause");
return;
}
}
}
a、 核對賬戶是否存在遍歷所有賬戶,若存在且賬戶狀態(tài)良好(即為0)返回該賬戶下標,否則返回-1
int validata_ID(char* p) {//查找賬戶是否存在,存在返回其角標k,否則返回-1
int i = 0;
if (strcmp(p_account[sign].xh, p) != 0) {//不是轉(zhuǎn)給自己
for (i = 0; i< cnt_account; i++)//轉(zhuǎn)賬的賬戶存在
if (strcmp(p, p_account[i].xh) == 0)
if (p_account[i].zt == '0') return i;//轉(zhuǎn)賬的賬戶狀態(tài)良好
}
return -1;
}
b、 核對金額是否合法轉(zhuǎn)賬金額:非負、50的倍數(shù)、小于單筆最高轉(zhuǎn)賬金額、余額充足
int validata_Money(int money) {//轉(zhuǎn)賬金額合法返回值為1,否則-1
if (money >= 0 && money % 50 == 0 && money<= MAX_MONEY)
if (money<= p_account[sign].ye) return 1;
return -1;
}
5、修改密碼輸入原密碼:核對,若輸錯原密碼三次可鎖定賬戶(此項本程序未實現(xiàn))
輸入新密碼:三次新密碼要一致才能修改原密碼,修改完之后要重新登錄
void ChangePwd() {//修改密碼
char ori_mm[MAX_PASSWORD];
char new_mm1[MAX_PASSWORD], new_mm2[MAX_PASSWORD], new_mm3[MAX_PASSWORD];
int times = 0;//記錄輸入次數(shù)
printf("請輸入原密碼:>"); scanf("%s", ori_mm);
if (strcmp(ori_mm, p_account[sign].mm) == 0) {puts("密碼正確!"); system("pause");//下一步
system("cls");
printf("請輸入新密碼:>"); scanf("%s", new_mm1);
puts("輸入成功,請再次輸入!"); system("pause");
do { system("cls");
printf("請再次輸入新密碼:>"); scanf("%s", new_mm2);
times++;
if (strcmp(new_mm1, new_mm2) == 0) {//判斷兩次密碼是否一致
puts("輸入成功,請再次輸入!"); system("pause");
break;
}
else { if (times == 3) {printf("%d次輸入密碼不一致,無法修改密碼!\n", times);
return;
}
puts("兩次密碼不一致,請重新輸入!"); system("pause");
}
} while (1);
do { system("cls");
times = 0;//將次數(shù)記錄恢復(fù)到0,進行下次記錄
printf("請再次輸入新密碼:>"); scanf("%s", new_mm3);
times++;
//判斷三次密碼是否一致
if (strcmp(new_mm3, new_mm2) == 0) { strcpy(p_account[sign].mm, new_mm3);//修改密碼
puts("輸入成功,密碼已修改,請重新登錄!"); system("pause"); Login();
break;
}
else { if (times == 3) {printf("%d次輸入密碼不一致,無法修改密碼!\n", times);
return;
}
puts("密碼輸入不一致,請重新輸入!"); system("pause");
}
} while (1);
}
else {puts("原密碼輸入有誤,無法修改密碼!"); system("pause");
}
}
6、銷戶此功能為銀行人員使用?。?!
void Logout() {//銷戶
char ori_mm[MAX_PASSWORD];
int n = 0,i = 0;
printf("請輸入原密碼:>"); scanf("%s", ori_mm);
if (strcmp(ori_mm, p_account[sign].mm) == 0) {system("cls");
puts("您確定要注銷您的賬戶嗎?\t確定請按<1>");
printf("請選擇:>"); scanf("%d", &n);
if (n == 1) { for (i = sign; i< cnt_account; i++) { p_account[i] = p_account[i + 1];
}
cnt_account--;
puts("銷戶成功!\n"); system("pause");
}
}
else {puts("密碼錯誤,無法銷戶!"); system("pause");
}
}
補充功能
輸入時密碼隱藏輸入密碼時,用*代替打印到屏幕上
1、中有一個 _getch() 函數(shù),當使用它的時候不會回顯字符。
2、‘\r’ 表示回車符;‘\b’ 表示退格符,當按下 “backspace” 時就是輸入了 ‘\b’ 退格:光標往前一格,而原來位置顯示的字符不變
void InPwd() {char ch;
int index = 0;
char password[MAX_PASSWORD];
puts("請輸入密碼,以回車鍵結(jié)束");
while ((ch = _getch()) != '\r') {if (ch != '\b') { printf("*");//判斷若輸入非退格符則顯示 *
password[index++] = ch;//將ch讀入到password中
}
else { //若為退格符,則需先顯示 '\b' 使得光標往前一格,再
//顯示空格符覆蓋掉原來的 * ,最后再顯示 '\b’使光標
//回退,達到視覺上的刪除效果
printf("\b \b");
index--;
}
}
password[index] = '\0';
printf("\n");
//打印到屏幕上檢查輸入是否一致
printf("所輸密碼為:%s\n", password);//使用時不需要寫這一句
system("pause");
}
四、執(zhí)行結(jié)果執(zhí)行結(jié)果均以一 段 路三人來演示
開戶界面
一 段 路三人開戶結(jié)果
存錢與改密碼
存入金額與新密碼情況如下:
一:1000 123456
二:2000 234567
三:3000 345678
讓路給一轉(zhuǎn)賬1000元,使得三人余額均為2000元
其他功能的操作這里就不展示了,有興趣的小猿自己操作哦?。?! 不足之處,歡迎評論區(qū)留言?。?!
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧