1. 程式人生 > 實用技巧 >C++ 指標的錯誤釋放

C++ 指標的錯誤釋放

部落格班級 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

實驗小結

通過此次實驗我發現我有許許多多的不足點,首先檔案部分掌握不夠,連結串列掌握的也不是很好,通過各種途徑學習才完成本次實驗,希望在日後的學習中可以做到更好