C++ 指標的錯誤釋放
阿新 • • 發佈:2020-11-18
部落格班級 | https://edu.cnblogs.com/campus/ahgc/AHPU-se-JSJ18 |
---|---|
作業要求 | https://edu.cnblogs.com/campus/ahgc/AHPU-se-JSJ18/homework/11478 |
作業目標 | 編寫一個ATM系統語言不限 |
學號 | 3180701114 |
一.題目要求
編寫一個ATM管理系統,語言不限,要求應包括以下主要功能:
(1)開戶,銷戶
(2)查詢賬戶餘額
(3)存款
(4)取款
(5)轉賬(一個賬戶轉到另一個賬戶)等...
允許網上查詢參考,但請注意不要直接抄襲,可以理解看懂別人的程式碼,再自己編寫
二.程式碼提交
(1)提交你的原始碼在部落格上,請注意不要整體貼上上來就結束了,最好把你的程式碼分模組提交,相應模組給出完整解釋,主要程式碼給出註釋,要注意程式碼書寫規範,養成好習慣
(2)請把你的程式主要執行介面一同貼上來
程式碼部分
標頭檔案
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> #include <conio.h> #include <windows.h> #define N 20 void Initial(); //初始化介面 void BuildUser(); //管理員新建使用者 int UserLogin(); //使用者登陸介面 void AdminLogin(); //管理員登陸介面 void Menu(int n); //主界選單 void ChangePassword(); //密碼修改
定義結構體
typedef struct User //使用者資料結構體 { char UserID[N]; //使用者ID char Name[N]; //姓名 char UserPassword[N]; //使用者密碼 float money; //使用者當前餘額 char time[N]; //使用者最後一次使用系統時間 }USERDATA; typedef struct D //使用者操作日誌結構體 { char id[N]; char o; char money; char balance; char tim[N]; }PDATA;
float MoneySave(struct User *p); //存款函式
float DrawMoney(struct User *p); //取款函式
float Trans(struct User *p); //轉賬函式
void Balance(); //檢視餘額
USERDATA userdata[500];
int main()
{
system("cls"); //清屏
system("title ATM終端模擬系統");
system("color 0b");
Initial();
//printf("除錯");
return 0;
}
主介面
void Initial()
{
system("cls");
int a,ret,b;
do{ //錯誤輸入非1或2,重新輸入
printf("\n\n\n \n");
printf(" 歡迎使用 ATM 終端服務系統\n\n");
printf(" ------------------------------------------------- \n\n");
printf(" 請輸入您的選擇 :\n\n");
printf(" ------------------------------------------------- \n\n");
//printf(" _________________________________________________\n");
printf(" 1 使用者登入 \n\n\n");
//printf(" _________________________________________________\n");
printf(" 2 前臺服務 \n\n\n");
printf(" 3 退出系統 \n\n\n");
printf(" -------------------------------------------------\n");
printf("\t\t\t\t\t\t\t");
system("date /t");
printf("\t\t\t\t\t\t\t");
system("time /t");
do{ //實現檢錯,錯誤輸入重新輸
//printf(" 重新輸入您的選擇 :\n");
printf(" ------------");
scanf("%d",&a);
switch(a) //初始選項 非1,2重新輸入。
{
case 1: b=1;break;
case 2: b=1;break;
case 3: exit(0);break;
default:
printf(" ");
printf("錯誤輸入,請重試。\n");break;
}
getchar();
}while(b!=1);
if(a==1)
{
ret=UserLogin(); //使用者登入
Menu(ret); //選單
ret=1;
}
else if(a==2)
{
system("cls"); //清屏
AdminLogin();
ret=1;
}
}while(ret!=1);
}
開啟檔案
int UserLogin()
{
char a[N],b[N];
FILE *fp;
if((fp=fopen("iddata.txt","a+"))==NULL) //開啟檔案
{
printf("開啟失敗\n");
exit(0);
}
int i=0,j,k=0,s;
do{
fscanf(fp,"%s%s%s%f",&userdata[i].Name,&userdata[i].UserID,&userdata[i].UserPassword,&userdata[i].money);//將檔案中的資料讀入記憶體
i++;
}while(!feof(fp)); //判斷是否到檔案結尾
fclose(fp); //關閉檔案
system("cls");
printf("\n\n\n\n\n 請輸入使用者賬號:");
//printf(" ");
gets(a);
printf("\n\n 請輸入使用者密碼:");
//printf(" ");
gets(b);
for(j=0;j<i;j++)
{
if(strcmp(a,userdata[j].UserID)==0)
{
for(k=0;k<2;k++)
{
if(strcmp(b,userdata[j].UserPassword)==0) //比較使用者賬戶密碼是否輸入正確
return j;
else
{
printf("\n\t\t ");
printf("密碼錯誤請重新輸入:");
gets(b);
}
}
printf("\n\n\t\t ");
printf("密碼已輸入錯誤三次,即將退出程式。\n");
printf(" ");
getch();
Initial(); // 返回初始介面
}
}
printf("\n\n\n\t\t 查無該使用者,請檢查後重新輸入。\n");
getch();
UserLogin();
}
管理員登陸
void AdminLogin()
{
char adminID[N]="1",adminPassword[N]="1";//管理員id 和 密碼
char a[N],b[N];
int i=0,j=0,s;
/* FILE *fp;
if((fp=fopen("admin.txt","r"))==NULL)
{
printf("Failure to open admin.txt!\n");
exit(0);
}
fscanf(fp,"%s%s",adminID,adminPassword); //將管理員的ID和Password從檔案中讀入記憶體
fclose(fp);*/
do{
printf("\n\t\t\t請輸入管理員賬號:");
gets(a);
printf("\n\t\t\t請輸入管理員密碼:");
gets(b);
if(strcmp(a,adminID)==0) //判斷管理員賬號是否相同
{
if(strcmp(b,adminPassword)==0)
{
printf("\n\t\t\t登陸成功,請按任意鍵開始錄入使用者。\n");
getch();
system("cls");
BuildUser();
printf("\n\t\t\t錄入完成,退出程式");
exit(0);
}
else
{
printf("\n\t\t\t密碼錯誤,請重新輸入。\n"); //判斷管理員賬號密碼是否正確
s=1;
}
}
else
{
printf("\n\t\t\t賬號密碼不匹配,請重試。\n");
s=1;
}
if(s==1)
{
getch();
system("cls");
}
}while(s==1);
}
主選單介面
void Menu(int n)
{
FILE *fp,*fp1;
time_t timep;
time(&timep); //取當前系統時間
int i=0,o;float money=0;
if((fp=fopen("iddata.txt","a+"))==NULL)
{
printf("\n\t\t\t開啟失敗\n");
exit(0);
}
do{
fscanf(fp,"%s%s%s%f",&userdata[i].Name,&userdata[i].UserID,&userdata[i].UserPassword,&userdata[i].money);
i++;
}while(!feof(fp)); //printf("除錯");
fclose(fp);
char path[30]="H:\\1\\ATM\\private_record\\",suffix[]=".txt";
strcat(path,userdata[n].UserID);
strcat(path,suffix);
if((fp1=fopen(path,"r+"))==NULL)
{
fp1=fopen(path,"w+");
fprintf(fp1,"%-20s%-10s%-10s%-10s% 10s\n","賬號","操作","金額","餘額","時間");
}
else fp=fopen(path,"a+");
//money=0;
do{
system("cls");
printf("\n\n\t\t ");
//printf(" ------------ \n\n");
printf("\t\t");
printf("請選擇您的操作:\n\n");
printf("\t\t ");
printf("-----------------------------------------\n");
printf("\n\t\t ");
printf(" 1.使用者存款 \n");
printf("\n\t\t ");
printf(" 2.使用者取款 \n");
printf("\n\t\t ");
printf(" 3.使用者轉賬 \n");
printf("\n\t\t ");
printf(" 4.檢視餘額 \n");
printf("\n\t\t ");
printf(" 5.修改密碼 \n");
printf("\n\t\t ");
printf(" 6.退出登入 \n\n");
printf("\t\t ");
printf("=========================================\n");
printf("\t\t ");
printf("------------");
scanf("%d",&o);
switch(o)
{
case 1:system("cls");money=MoneySave(&userdata[n]);break; //1.使用者存款
case 2:system("cls");money=DrawMoney(&userdata[n]);break; // 2.使用者取款
case 3:system("cls");money=Trans(&userdata[n]);break; // 3.使用者轉賬
case 4:printf(" ");
printf("你的當前餘額為:%.2fRMB。\n",userdata[n].money);//使用者轉賬
printf(" ");
printf("請按鍵返回。");getch();break;
case 5:ChangePassword();break; //修改密碼
case 6:printf(" ");
printf("歡迎下次使用,謝謝。\n");getch();break; // 退出程式
}
time(&timep); //獲取系統時間
if(o!=4&&o!=5&&money!=0)
{
if(o==6)
money=0;
fprintf(fp1,"%-20s%-10d%-10.2f%-10.2f%10s\n",userdata[n].UserID,o,money,userdata[n].money,ctime(&timep));
}
}while(o!=6);
fclose(fp1);
if(o==6)
main();
}
錄入使用者資訊
void BuildUser()
{
printf("\n\t\t\t開始錄入使用者:\n");
USERDATA userdata;
int i=0;FILE *fp; //判斷是否繼續錄入,如果繼續按1,否則按2
char ch;
if((fp=fopen("iddata.txt","a+"))==NULL)
{
printf("Failure to open admin.txt!\n");
exit(0);
}
do{
system("cls");
printf("\n\t\t\t繼續錄入使用者:\n");
printf("\n\t\t\t請輸入使用者姓名:");
gets(userdata.Name);
printf("\n\t\t\t請輸入使用者卡號:");
gets(userdata.UserID);
printf("\n\t\t\t請輸入使用者密碼:");
gets(userdata.UserPassword);
printf("\n\t\t\t請輸入使用者當前金額:");
scanf("%f",&userdata.money);
fprintf(fp,"%-10s%-10s%-10s%-10.2f\n",userdata.Name,userdata.UserID,userdata.UserPassword,userdata.money); //見錄入資料儲存到檔案中
system("cls");
printf("\n\t\t\t錄入成功。\n\t\t\t繼續錄入請按 1 \n\t\t\t結束錄入並推出登陸請按 2\n");
printf("\t\t\t----");
scanf("%d",&i);
ch=getchar();
}while(i==1);
fclose(fp);
if(i==2) main();
}
存錢操作
float MoneySave(struct User *p)
{
float money;
printf("\t\t\t");
printf("請輸入您的存款金額:");
do{
scanf("%f",&money);
if((int)money%50!=0){ //判斷存款金額是否是50的倍數
printf("\t\t\t");
printf("對不起,只能識別面值為50或100的鈔票。\n\n\t\t\t請重新開始你的存款:");}
}while((int)money%50!=0);
p->money+=money;
printf("\t\t\t");
printf("成功存入%.2f元,請按任意返回繼續操作。\n",money);
printf(" ");
getch();
return money;
}
float DrawMoney(struct User *p)
{
float money;
int s=0;
printf("\n\t\t\t請輸入您的取款金額:"); //取款
do{
scanf("%f",&money);
if(money>p->money)
{
printf("\n\t\t\t您卡里沒有辣麼多錢了\n");
printf("\n\t\t\t按任意鍵返回,查詢餘額。");
getch();
return 0;
}
if(money>2500)
{
printf("\n\t\t\t一次最多可以取2500元,請重新輸入取款金額:");//一次最多不能取超過2500元
}
if((int)money%50!=0)
{
printf("\n\t\t\t只能取出面值為50或100的RMB。\n\n\t\t\t請再次輸入您的取款金額:");
}
}while(money>2500||(int)money%50!=0);
p->money-=money;
printf("\n\t\t\t成功取出%.2f元。請按任意鍵返回上層。\n",money);
getch();
return -money;
}
轉賬操作
float Trans(struct User *p)
{
FILE *fp;
char a[N];
float money;
printf("\n\t\t\t請輸入您要轉賬的同行賬戶:");
re:
scanf(" %s",a);
char path[30]="G:\\1\\ATM\\private_record\\",suffix[]=".txt";
strcat(path,a);
strcat(path,suffix);
if((fp=fopen(path,"r+"))==NULL)
{
fp=fopen(path,"w+");
printf("\n\t\t\t該賬戶不存在,請重新輸入轉賬賬戶:");
goto re;
}
else
{
printf("\n\t\t\t請輸入轉賬金額:");
scanf("%f",&money);
while(money>p->money||money<=0)
{
if(money>p->money)
{
printf("\n\t\t\t您卡里沒有辣麼多錢了\n");
printf("\n\t\t\t請先按鍵查詢餘額後重新確認轉賬金額。");
printf("\t\t ");
getch();return 0;
break;
}
}
p->money-=money;
printf("\n\t\t\t成功轉入目標賬戶%.2f元,按任意鍵返回上層\n",money);
fclose(fp);
printf(" ");
getch();
return -money;
}
}
修改密碼
void ChangePassword()
{
char str1[7],str2[7];
do{
printf("\n\t\t\t請輸入新的密碼,密碼為6位:");
scanf("%s",str1);
printf("\n\t\t\t請再輸入一次:");
scanf("%s",str2);
if(strcmp(str1,str2)!=0)
{
printf("\n\t\t\t你輸入的密碼有誤,請重新輸入一遍:");
}
}while(strcmp(str1,str2)!=0);
printf("\n\t\t\t密碼修改成功,請選擇其他操作。");
getch();
}
psp表格
psp2.1 | 任務內容 | 計劃需要完成的時間(min | 實際完成需要的時間(min) |
---|---|---|---|
Planning | 計劃 | 300 | 360 |
Estimate | 估計這個任務需要多少時間,並規劃大致工作步驟 | 360 | 360 |
Development | 開發 | 20 | 15 |
Analysis | 需求分析(包括學習新技術) | 30 | 30 |
Design Spec | 生成設計文件 | 40 | 30 |
Design Review | 設計複審 | 30 | 30 |
Coding Standard | 程式碼規範 | 20 | 15 |
Design | 具體設計 | 20 | 10 |
Coding | 具體編碼 | 100 | 120 |
Code Review | 程式碼複審 | 10 | 20 |
Test | 測試(自我測試,修改程式碼,提交修改) | 10 | 15 |
Reporting | 報告 | 20 | 20 |
Test Report | 測試報告 | 20 | 15 |
Size Measurement | 計算工作量 | 20 | 10 |
Postmortem & Process Improvement Plan | 事後總結,並提出過程改進計劃 | 20 | 20 |
實驗小結
通過此次實驗我發現我有許許多多的不足點,首先檔案部分掌握不夠,連結串列掌握的也不是很好,通過各種途徑學習才完成本次實驗,希望在日後的學習中可以做到更好