1. 程式人生 > 實用技巧 >SDS-簡單動態字串

SDS-簡單動態字串

ATM管理系統

軟體工程導論 https://edu.cnblogs.com/campus/ahgc/AHPU-SE-19
作業要求 https://edu.cnblogs.com/campus/ahgc/AHPU-SE-19/homework/11477
作業目標 設計程式實現開戶、登入、查詢、存取款等功能
學號 3190704209

程式碼:

主要函式程式碼:

函式的宣告:

void chaxun(struct per *head);    
void kaihu(struct per *head);
void denglu(struct per *head);
void caidan(struct per *head);
void qukuan(struct per *head);
void xgmm(struct per *head);
void cunkuan(struct per *head);
void zhuanzhang(struct per *head);
void xiaohu(struct person **Phead);
void tuichu();
void menu();

選單函式:

void caidan(struct per *head)
{
	head=NULL;
	int i;      //i為客戶選擇輸入的變數
	while(1)
	{
		printf("請選擇您需要的業務:\n");      //銀行業務選單
		printf("*********************************\n");
		printf("**  1 取款   *****   2 查詢    **\n");
		printf("*********************************\n");
		printf("**  3 轉賬   *****   4 修改密碼**\n");
		printf("*********************************\n");
		printf("**  5 存款   *****   6 退出    **\n");
		printf("*********************************\n");
		scanf("%d",&i);
		if(i<6||i>0)
		{
			switch(i)
			{
			case 1:qukuan(head);       //呼叫銀行取款函式
			       system("pause");
				   system("cls");
				   break;
			case 2:system("cls");
				   chaxun(head);  //呼叫銀行查詢函式
				   break;
            case 3:system("cls");
				   zhuanzhang(head);  //呼叫銀行轉賬函式
				   break;
            case 4:system("cls");
				   xgmm(head);  //呼叫銀行修改密碼函式
				   break;
            case 5:system("cls");
				   cunkuan(head);  //呼叫銀行存款函式
				   break;
            case 6:system("cls");
				   tuichu();  //呼叫銀行退出函式
				   break;
			}
		}
		else
		{
			printf("您的輸入有誤\n");
			system("pause");
			system("cls");
		}
	}
}

開戶函式:

void kaihu(struct per *head)
{
	head=NULL;
	FILE *fp;   //定義檔案指標
	struct per *p1=NULL,*p2=NULL;   //p1,p2為定義連結串列指標
	p1=(struct per*)malloc(sizeof(struct per));  //開闢記憶體單元
	      printf("請輸入您的姓名:\n");  //請資料輸入連結串列中
		  scanf("%s",p1->name);
		  printf("請設定您的卡號:\n");
		  scanf("%s",p1->ID);
		  printf("請設定您銀行卡密碼:\n");
		  scanf("%s",p1->mima);
		  p1->money=0;
		  p1->next=NULL;
		  printf("您的個人資訊為");
		     printf("姓名:%s \n卡號:%s \n餘額:%4d\n",p1->name,p1->ID,p1->money);
          if(NULL==head)           //為新使用者開闢記憶體單元
		  {
			  head=(struct per *)malloc(sizeof(struct per));
			  head->next=p1;    //進行頭插法,將其作為第一個節點
		  }
		  else    //為新增客戶開闢記憶體單元
		  {
			  for(p2=head;p2->next!=NULL;p2=p2->next); //進行尾插
			  p2->next=p1;
		  }
		  if((fp=fopen("save.txt","ab+"))==NULL) //開啟檔案
		  {
			  printf("cannot poen file\n");
			  return;
		  }
		  if(fwrite(p1,sizeof(struct per),1,fp)!=1)  //將連結串列資訊寫入檔案中
			  printf("file write error\n");
		      fclose(fp);
			  printf("\n");
			  printf("恭喜您開戶成功,請登入\n");
			  system("pause");
			  system("cls");
			  denglu(head);
}

銷戶函式:

void xiaohu(struct person **Phead)   //*(*Phead)為指向結構體指標的地址
{
	char k[20];    //定義輸入查詢客戶姓名卡號的變數
	struct person *p=*Phead,*t;
	if(NULL==(*Phead))     //若指標最後指向空,則沒有客戶資訊
	{
		printf("沒有賬戶資訊可刪除!\n");
		return;
	}
	printf("請選擇要登出的卡號:\n");
	scanf("%s",k);
	if(p->kehu.ID==k)//若第一個客戶就是,則讓頭指標指向下一個結點
		*Phead=(*Phead)->next,free(p);
	else
	{
		while(NULL==p->next&&p->next->kehu.ID!=k)   //遍歷尋找,核對客戶卡號
			p=p->next;   //當p->next沒指向空,並且客戶的卡號還沒找到,則繼續尋找
		if(p->next==NULL)
			printf("對不起,沒有該賬戶!\n");
		else
		{
			t=p->next;  //如果找到,則把p->next的值賦給t
			p->next=p->next->next;
		}
		printf("刪除成功!");
	}
}

登入函式:

void denglu(struct per *head)
{
	char d[20];
	char mima[20];
	int i,j;
	FILE *fp;     //定義檔案指標
	struct per *p,*q=NULL;
	if((fp=fopen("save.txt","rb+"))==NULL)   //開啟一個二進位制檔案,為讀方式
	{
		printf("不能開啟檔案\n");   //如不能開啟,則結束程式
	}
	p=(struct per*)malloc(sizeof(struct per));   //申請空間
	head=p;
	while(!feof(fp))       //迴圈讀資料直到檔案尾結束
 
	{
		if(1!=fread(p,sizeof(struct per),1,fp))
			break;   //如果沒讀到資料,跳出迴圈
		p->next=(struct per *)malloc(sizeof(struct per));  //為下一個結點申請空間
		q=p;  //儲存當前節點的指標,作為下一結點的前驅
		p=p->next;  //指標後移,新讀入資料鏈到當前表尾
		
	}
	q->next=NULL;  //最後一個結點的後繼指標為空
	fclose(fp);
	printf("  **********************\n");
	printf("  ***歡迎ATM自助系統***\n");
	printf("  **********************\n");
	for(j=1;j<4;j++)      //限制卡號輸入的次數的迴圈
	{
		printf("請輸入您的卡號\n");
		scanf("%s",d);
		for(q=head;q!=NULL;q=q->next)   //遍歷連結串列
		{
			if(strcmp(q->ID,d)!=0)  //核對賬號
			{
			continue;   //跳出迴圈
			}
					else
		{
			for(i=1;i<4;i++)   //限制密碼輸入的次數的迴圈
			{
				printf("\n\n請輸入您的密碼\n");
				scanf("%s",mima);
				if(strcmp(q->mima,mima)!=0)      //核對密碼
				{
					printf("密碼不正確。請重新輸入密碼\n");
					system("pause");
					system("cls");
					continue;    //若密碼不對,跳出迴圈
				}
				else
				{
					system("cls");
					caidan(head);   //呼叫選單函式
				}
			}
			printf("\n\n\n您輸入密碼三次錯誤,謝謝光臨\n");
			system("pause");
			system("cls");
			exit(0);
		}
	}
		
	
	printf("\n\n\n您輸入的卡號有誤,請重試\n");
	system("pause");
	system("cls");
}
printf("您的卡號三次輸入錯誤,謝謝使用\n");
exit(0);
}
 

查詢存款:

void chaxun(struct per *head)
{
	head=NULL;  //連結串列頭指標
	FILE *fp;  //定義檔案指標
	struct per *p,*q=NULL;
	if((fp=fopen("save.txt","rb+"))==NULL)  //開啟一個二進位制檔案,為讀方式
	{
		printf("不能開啟檔案\n");  //如不能開啟,則結束程式
	}
	p=(struct per*)malloc(sizeof(struct per));   //申請空間
	head=p;
	while(!feof(fp))    //迴圈讀資料直到檔案尾結束
	{
		if(1!=fread(p,sizeof(struct per),1,fp))
			break;    //如果沒讀到資料,跳出迴圈
		p->next=(struct per *)malloc(sizeof(struct per));  //為下一個結點申請空間
		q=p;   //儲存當前結點的指標,作為下一個結點的前驅
		p=p->next;   //指標後移,新讀入資料鏈到當前表尾
	}
	q->next=NULL;   //最後一個結點的後繼指標為空
	fclose(fp);
	printf("您卡上現有餘額%d元\n\n",q->money);
	system("pause");
	system("cls");
}

存款:

void cunkuan(struct per *head)
{
	int i;
	head=NULL;   //連結串列頭指標
	FILE *fp;  //定義檔案指標
	struct per *p,*q=NULL;
	if((fp=fopen("save.txt","rb+"))==NULL)  //開啟一個二進位制檔案,為讀方式
	{
		printf("不能開啟檔案\n");  //如不能開啟,則結束程式
	}
	p=(struct per*)malloc(sizeof(struct per));   //申請空間
	head=p;
	while(!feof(fp))    //迴圈讀資料直到檔案尾結束
	{
		if(1!=fread(p,sizeof(struct per),1,fp))
			break;    //如果沒讀到資料,跳出迴圈
		p->next=(struct per *)malloc(sizeof(struct per));  //為下一個結點申請空間
		q=p;   //儲存當前結點的指標,作為下一個結點的前驅
		p=p->next;   //指標後移,新讀入資料鏈到當前表尾
	}
	q->next=NULL;   //最後一個結點的後繼指標為空
	fclose(fp);
	system("cls");
	printf("您卡上原有餘額%d元\n",q->money);   
    printf("  1: 100元        2:200元  \n");
    printf("  3: 300元        4:400元  \n");
    printf("  5: 500元        6:600元  \n");
    printf("請選擇您要存入的餘額\n");
	scanf("%d",&i);
	if(i>6||i<=0)
	{
		printf("對不起,您的輸入有誤\n\n");
		return;
	}
	else
	{
		i=100*i;
		q->money+=i;
		if((fp=fopen("save.txt","wb+"))==NULL)   //開啟檔案
		{
			printf("cannot open file\n");
		}
		if(fwrite(q,sizeof(struct per),1,fp)!=1)  //將修改的密碼重新寫入檔案
			printf("file write error\n");
	    	printf("您已經成功存取%d元\n",i);
			q->next=NULL;
			fclose(fp);
			system("pause");
			system("cls");
	}
}

取款:

void qukuan(struct per *head)
{
	head=NULL;   //head為連結串列頭指標
	int i;
	FILE *fp;          //定義檔案指標
	struct per *p,*q=NULL;
	if((fp=fopen("save.txt","rb+"))==NULL) //開啟一個二進位制檔案,為讀方式
	{
		printf("不能開啟檔案\n");  //如不能開啟,則結束程式
	}
	p=(struct per*)malloc(sizeof(struct per));  //申請空間
	head=p;
	while(!feof(fp))   //迴圈讀資料直到檔案尾結束
	{
		if(1!=fread(p,sizeof(struct per),1,fp))
			break;   //如果沒有讀到資料,跳出迴圈
		p->next=(struct per *)malloc(sizeof(struct per));  //為下一個結點申請空間
		q=p;   //儲存當前結點的指標,作為下一個結點的前驅
		p=p->next;  //指標後移,新讀入資料鏈到當前表尾
	}
	q->next=NULL;  //最後一個結點的後繼指標為空
	fclose(fp);
	system("cls");
    printf("  1: 100元        2:200元  \n");
    printf("  3: 300元        4:400元  \n");
    printf("  5: 500元        6:600元  \n");
    printf("請按要求選擇您要取款的金額\n");
	scanf("%d",&i);
	if(i>6||i<=0)    //限制輸入範圍
	{
		printf("對不起,您的輸入有誤\n\n");
		return;
	}
	else
	{
		i=100*i;  //對應選項乘以一百為取款金額
		if(i>q->money)
		{
			printf("對不起,您的金額不足\n");
			system("pause");
			system("cls");
			caidan(head);   //呼叫取款機選單函式
		}
		else
		{
			q->money-=i;  //對金額進行處理
			if((fp=fopen("save.txt","wb+"))==NULL)  //開啟檔案
			{
				printf("cannot open file\n");
				return;
			}
			if(fwrite(q,sizeof(struct per),1,fp)!=1) //將修改的資訊重新寫入檔案
				printf("file write error\n");
			printf("您已經成功取走%d元\n",i);
			q->next=NULL;
			fclose(fp);    //關閉檔案
		}
		
	}
}

轉賬:

void zhuanzhang(struct per *head)
{
	head=NULL;
	FILE *fp;  //定義檔案指標
	struct per *p,*q=NULL;
	if((fp=fopen("save.txt","rb+"))==NULL)  //開啟一個二進位制檔案,為讀方式
	{
		printf("不能開啟檔案\n");  //如不能開啟,則結束程式
	}
	p=(struct per*)malloc(sizeof(struct per));   //申請空間
	head=p;
	while(!feof(fp))    //迴圈讀資料直到檔案尾結束
	{
		if(1!=fread(p,sizeof(struct per),1,fp))
			break;    //如果沒讀到資料,跳出迴圈
		p->next=(struct per *)malloc(sizeof(struct per));  //為下一個結點申請空間
		q=p;   //儲存當前結點的指標,作為下一個結點的前驅
		p=p->next;   //指標後移,新讀入資料鏈到當前表尾
	}
	q->next=NULL;   //最後一個結點的後繼指標為空
	fclose(fp);
	int i,j,k;
	printf("請輸入帳號號碼\n");
	scanf("%d",&i);
	printf("請再次輸入帳號號碼\n");   //核對卡號
	scanf("%d",&j);
	if(i!=j)
	{
		printf("兩次賬號不同,請重新輸入\n");
		zhuanzhang(head);
	}
	else
	{
		system("cls");

    printf(" 1: 100元         2:200元  \n");

    printf(" 3: 300元         4:400元  \n");

    printf(" 5: 500元         6:600元  \n");
    printf("請輸入轉賬金額\n");
	scanf("%d",&k);
	if(k>6||k<=0)
	{
		printf("對不起,您的輸入有誤\n\n");
		return;
	}
	else
	{
		k=k*100;
		if(k>q->money)    //對餘額進行判斷
		{
			printf("對不起,您的餘額不足\n");
			system("pause");
			system("cls");
			caidan(head);
		}
		else
		{
			printf("您已成功轉賬%d元\n",k);
			q->money-=k;
			if((fp=fopen("save.txt","wb+"))==NULL)
			{
				printf("cannot open file\n");
				return;
			}
			if(fwrite(q,sizeof(per),1,fp)!=1)  //將資料重新寫入檔案
				printf("file write error\n");
			q->next=NULL;
			fclose(fp);
			system("pause");
			system("cls");
		}
	}
	}
}

部分執行截圖:

個人小結


<![endif]>

psp2.1 任務內容 計劃完成需要的時間(min) 實際完成需要的時間(min)
Planning 計劃 20 10
Estimate 估計這個任務需要多少時間,並規劃大致工作步驟 20 20
Development 開發 120 180
Analysis 需求分析(包括學習新技術) 20 10
Design Spec 生成設計文件 5 10
Design Review 設計複審 5 10
Coding Standard 程式碼規範 5 10
Design 具體設計 20 30
Coding 具體編碼 60 80
Code Review 程式碼複審 10 10
Test 測試(自我測試,修改程式碼,提交修改) 5 20
Reporting 報告 7 10
Test Report 測試報告 5 10
Size Measurement 計算工作量 5 10
Postmortem & Process Improvement Plan 事後總結,並提出過程改進計劃 5 10

通過這次的ATM系統設計使我對於自己所掌握的知識有了新的理解與認知,使得我意識到了自己對於檔案讀寫這一部分的理解依舊不夠,需要進一步的學習加強。