C語言及程式設計進階例程-2 一個程式,多個檔案
演示:建立多檔案的專案
main.c
#include <stdio.h>
int max(int x,int y);
int main( )
{
int a,b,c;
printf("輸入兩數:");
scanf("%d %d", &a, &b);
c=max(a,b);
printf("max=%d\n", c);
return 0;
}
max.c
int max(int x,int y)
{
int z;
z=x>y?x:y;
return(z);
}
演示:銀行儲蓄系統
main.c
#include <stdio.h> #include "bank.h" /*主函式:*/ int main() { printf("+----------------------+\n"); printf("+ 歡迎光臨CSDN銀行 +\n"); printf("+----------------------+\n"); if (pass()) { readData(); work(); writeData(); } return 0; }
bank.h
#ifndef BANK_H_INCLUDED #define BANK_H_INCLUDED #define upNum 2000 //系統最多容納的使用者數 int user[upNum][3]; //賬號、密碼、狀態 char name[upNum][10]; //使用者名稱 double balance[upNum]; //賬戶餘額 //以上相同行下標,描述同一人的資訊 int N; //實際的使用者數目 int pass(); //業務員登入 void readData(); //開始前從檔案中讀資料,存在陣列中 void writeData(); //程式結束前,將陣列中的資料寫入到檔案中 void work(); //業務驅動 int chooseInMenu(); //顯示選單並由業務員選擇 void openAccount(); //開戶 void cancelAccount(); //登出賬戶 void save(); //存款 void withdraw(); //取款 void showAccount(); //查詢餘額 void transferAccounts(); //轉賬 void reportLoss(); //掛失 void cancelLoss(); //解除掛失 void updatePassword(); //更改密碼 int inputPassword(); //返回鍵盤輸入的密碼 int search(int); //根據賬號找到使用者資料對應的下標 #endif // BANK_H_INCLUDED
bank.c
#include <stdio.h> #include <conio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include "bank.h" /* 功能:驗證使用者密碼 返回值:密碼正確,返回1; 不能通過密碼驗證,返回0 */ int pass() { char sNameInFile[20]; //由檔案中讀出的業務員使用者名稱 char sPassInFile[20]; //檔案中儲存的密碼,這一版本中,用字元儲存密碼 char sName[20]; //業務員登入時輸入的使用者名稱 char sPass[20]; //業務員登入時輸入的密碼 char ch; int iTry=3; //進入系統時嘗試的次數 int right = 0; //要返回的結果:0-不正確 1-正確 FILE *fp; //用於檔案操作 //密碼儲存在檔案中,先取出 if ((fp=fopen("password.txt", "r"))==NULL) { printf("password file cannot open!"); exit(0); } fscanf(fp, "%s %s", sNameInFile, sPassInFile); //從檔案中讀業務員使用者名稱和密碼密碼 fclose(fp); //進入系統,密碼三次不對將退出 do { printf("請輸入業務員使用者名稱:"); scanf("%s", sName); printf("請輸入密碼:"); int i=0; while((ch=getch())!='\r') //getch在接受輸入後,不在螢幕上顯示 { sPass[i++]=ch; putchar('*'); //接受任何字元,螢幕上只顯示* } sPass[i]='\0'; fflush(stdin); printf("\n"); if(strcmp(sPass,sPassInFile)==0&&strcmp(sName,sNameInFile)==0) { right = 1; break; } else { iTry--; if(iTry>0) printf("超過3次將退出,你還可以嘗試%d次!\n", iTry); else { printf("對不起,你不能進入系統\n"); } } } while(iTry); return right; } /* 關於getch()的一點說明: 所在標頭檔案:conio.h 函式用途:從控制檯讀取一個字元,但不顯示在螢幕上 函式原型:int getch(void) 返回值:讀取的字元 在不同平臺,輸入回車,getch()將返回不同數值,而getchar()統一返回10(即\n) 1)windows平臺下ENTER鍵會產生兩個轉義字元 \r\n,因此getch返回13(\r)。 2)unix、 linux系統中ENTER鍵只產生 \n ,因此getch返回10(\n)。 3)MAC OS中ENTER鍵將產生 \r ,因此getch返回13(\r)。 為避免鍵盤快取區中未讀出的字元影響程式,用fflush(stdin);清除輸入快取區 */ /* 功能:辦理業務 */ void work() { int iChoice; //用於選擇系統功能 //辦理業務 do { iChoice = chooseInMenu(); //從選單中獲得功能程式碼 switch(iChoice) { case 1: openAccount(); //開戶 break; case 2: cancelAccount(); //登出賬戶 break; case 3: save(); //存款 break; case 4: withdraw(); //取款 break; case 5: showAccount(); //查詢餘額 break; case 6: transferAccounts(); //轉賬 break; case 7: reportLoss(); //掛失 break; case 8: cancelLoss(); //解除掛失 break; case 9: updatePassword(); //更改密碼 break; case 0: printf("歡迎您再來. \n"); } } while(iChoice); } /* 功能:從檔案中讀取儲戶資料 */ void readData() { FILE *fp; //用於檔案操作 int i = 0; //從檔案中取出餘額 if ((fp=fopen("account.dat", "r"))==NULL) { printf("data file cannot open!"); exit(0); } while(fscanf(fp,"%d %s %d %lf %d",&user[i][0], name[i], &user[i][1], &balance[i],&user[i][2] ) != EOF) { i++; } N = i; //用全域性變數儲存使用者的總人數 fclose(fp); return; } /* 功能:將使用者資料儲存到檔案中 */ void writeData() { FILE *fp; //用於檔案操作 int i=0; //儲存餘額 if ((fp=fopen("account.dat", "w"))==NULL) { printf("data file cannot open!"); exit(0); } for(i=0; i<N; i++) fprintf(fp,"%d %s %d %f %d\n",user[i][0], name[i], user[i][1], balance[i],user[i][2]); fclose(fp); } /* 功能:顯示選單並由業務員選擇 返回值:使用者選擇的功能,範圍0-9 */ int chooseInMenu() { int i; while(1) { printf("\n"); printf("+----------------------------+\n"); printf("+ 1 開戶 2 銷戶 3 存款 +\n"); printf("+ 4 取款 5 查詢 6 轉賬 +\n"); printf("+ 7 掛失 8 解掛 9 改密 +\n"); printf("+ 0 退出 +\n"); printf("+----------------------------+\n"); printf("請輸入操作指令:"); scanf("%d", &i); if(i>=0 && i<=9) break; else printf("請重新選擇功能\n\n"); } return i; } /* 功能:開戶 說明:在進入系統時,在讀入資料過程中,已經記錄了使用者數為N,在陣列中對應下標為0~N-1 開戶時要增加一個使用者,只要為下標為N的陣列元素置值,並在成功之後令N++即可。 這樣做順序增加簡單,但遺留的後患是,在查詢賬戶時,不得不用順序查詢,這在效率上是不划算的。 改進的手段(1):開戶時,根據賬號,將資料插入到陣列中,使按賬號有序,這樣做插入時麻煩,但有利於以後要頻繁的查詢操作 改進的手段(2):賬號由系統自動生成,保證其連續,這樣在順序增加的時候,就保證了其有序。 */ void openAccount() { if(N==upNum) { printf("銀行使用者數已經達到上限,不能再開戶"); return; } //下面正常辦理開戶業務 printf("正在開戶\n"); printf("賬號:"); scanf("%d", &user[N][0]); printf("戶主姓名:"); scanf("%s", name[N]); int iPass1, iPass2; printf("密碼:"); iPass1=inputPassword(); //輸入密碼1 printf("確認密碼:"); iPass2=inputPassword(); //輸入密碼2 if(iPass1==iPass2) { user[N][1]=iPass1; user[N][2]=0; //賬戶狀態為“正常” printf("存入金額:"); scanf("%lf", &balance[N]); N++; //正式使用者數增加1,確認了新使用者已經加入 printf("成功開戶!\n"); } else { printf("兩次密碼不一致,未成功開戶!\n"); //沒有N++,則讀入的值無效 } } /* 功能:登出賬戶 說明:找到賬戶,並將其狀態改為2-登出即可。 登出前應該檢查餘額,應該先取款再登出 */ void cancelAccount() { int id; //用於輸入的賬號 int who; //查詢到該賬號在陣列中對應的下標 int iPass; printf("待銷戶賬號:"); scanf("%d", &id); who = search(id); //根據賬號查詢使用者,返回使用者的下標 if(who<0) //說明id賬戶不存在 { printf("該使用者不存在,銷戶失敗!\n"); } else { printf("戶主姓名:%s\n", name[who]); printf("密碼:"); iPass=inputPassword(); if(iPass==user[who][1]) { printf("餘額:%.2f 元\n", balance[who]); printf("確認銷戶(y/n)?"); if(tolower(getchar())=='y') { balance[who]=0; //取款後餘額變0 user[who][2]=2; //狀態變為登出 printf("取款 %.2f 元,銷戶成功!\n", balance[who]); } else { printf("你取消了操作,銷戶失敗!\n"); } fflush(stdin); //清除了getchar()時在鍵盤快取中的遺留,以免影響後續操作 } else { printf("輸入的密碼錯誤,銷戶失敗!\n"); } } } /* 功能:存款 說明:需要保證賬戶存在,且處於正常狀態 */ void save() { int id, who; double money; printf("賬號:"); scanf("%d", &id); who = search(id); //根據賬號查詢使用者,返回使用者的下標 if(who<0) //說明id賬戶不存在 { printf("該使用者不存在,存款失敗!\n"); } else { if(user[who][2]==0) { printf("戶主姓名:%s\n", name[who]); printf("輸入存款額:"); scanf("%lf", &money); balance[who]+=money; printf("存款後,您有%.2f元. \n",balance[who]); } else if(user[who][2]==1) { printf("該使用者處於掛失狀態,存款失敗!\n"); } else { 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(user[who][2]==0) { printf("戶主姓名:%s\n", name[who]); printf("密碼:"); iPass=inputPassword(); if(iPass!=user[who][1]) { printf("輸入密碼錯誤,取款失敗!\n"); } else { printf("輸入取款額:"); scanf("%lf", &money); if(money>balance[who]) //親,不玩透支 { printf("餘額不足,取款失敗!\n"); } else { balance[who]-=money; printf("取款後,還有%.2f元. \n",balance[who]); } } } else if(user[who][2]==1) { printf("該使用者處於掛失狀態,取款失敗!\n"); } else { printf("該使用者已經銷戶,取款失敗!\n"); } } return; } /* 功能:查詢賬戶 說明:顯示賬戶資訊 */ void showAccount() { int id, who; int iPass; printf("賬號:"); scanf("%d", &id); who = search(id); //根據賬號查詢使用者,返回使用者的下標 if(who<0) //說明id賬戶不存在 { printf("該使用者不存在,查詢完畢!\n"); } else { printf("戶主姓名:%s\n", name[who]); printf("密碼:"); iPass=inputPassword(); if(iPass!=user[who][1]) { printf("輸入密碼錯誤,不能繼續查詢其他資訊!\n"); } else { printf("餘額:%.2f元. \n",balance[who]); printf("狀態:"); if(user[who][2]==0) { printf("正常\n"); } else if(user[who][2]==1) { printf("掛失\n"); } else { printf("已經銷戶\n"); } } } return; } /* 功能:轉賬 說明:需要保證兩個賬戶都存在,且處於正常狀態,另外,轉出賬戶的餘額要足夠 */ void transferAccounts() { int id, whoout, whoin; int iPass; double money; printf("輸入轉出賬號:"); scanf("%d", &id); whoout = search(id); //根據賬號查詢使用者,返回使用者的下標 if(whoout<0) //說明id賬戶不存在 { printf("該使用者不存在,轉賬失敗!\n"); } else { if(user[whoout][2]==0) { printf("戶主姓名:%s\n", name[whoout]); printf("密碼:"); iPass=inputPassword(); if(iPass!=user[whoout][1]) { printf("輸入密碼錯誤,轉賬失敗!\n"); } else { printf("輸入轉賬金額:"); scanf("%lf", &money); if(money>balance[whoout]) //親,不玩透支 { printf("餘額不足,轉賬失敗!\n"); } else { printf("輸入轉入賬號:"); scanf("%d", &id); whoin = search(id); //根據賬號查詢使用者,返回使用者的下標 if(whoin<0) { printf("轉入賬戶不存在,轉賬失敗!\n"); } else { if(user[whoin][2]>0) { printf("轉入賬戶異常,轉賬失敗!\n"); } else { balance[whoout]-=money; balance[whoin]+=money; printf("取款後,您還有%.2f元. \n",balance[whoout]); } } } } } else { printf("該賬戶異常,轉賬失敗!\n"); } } return; } /* 功能:掛失賬戶 */ void reportLoss() { int id, who; int iPass; printf("賬號:"); scanf("%d", &id); who = search(id); //根據賬號查詢使用者,返回使用者的下標 if(who<0) //說明id賬戶不存在 { printf("該使用者不存在,不能掛失!\n"); } else { printf("戶主姓名:%s\n", name[who]); printf("密碼:"); iPass=inputPassword(); if(iPass!=user[who][1]) { printf("輸入密碼錯誤,不能繼續操作!\n"); } else { if(user[who][2]==0) { user[who][2]=1; printf("掛失成功\n"); } else if(user[who][2]==1) { printf("該賬戶已經處於掛失狀態\n"); } else { printf("該賬戶已銷戶,不能掛失\n"); } } } return; } /* 功能:解除掛失 */ void cancelLoss() { int id, who; int iPass; printf("賬號:"); scanf("%d", &id); who = search(id); //根據賬號查詢使用者,返回使用者的下標 if(who<0) //說明id賬戶不存在 { printf("該使用者不存在,解除掛失失敗!\n"); } else { printf("戶主姓名:%s\n", name[who]); printf("密碼:"); iPass=inputPassword(); if(iPass!=user[who][1]) { printf("輸入密碼錯誤,不能繼續操作!\n"); } else { if(user[who][2]==0) { printf("該賬戶處於正常狀態,不需要解除掛失\n"); } else if(user[who][2]==1) { user[who][2]=0; printf("解除掛失成功\n"); } else { printf("該賬戶已銷戶,操作無效\n"); } } } return; } /* 功能:改密碼 */ void updatePassword() { int id, who; int iPass, iPass1, iPass2; printf("賬號:"); scanf("%d", &id); who = search(id); //根據賬號查詢使用者,返回使用者的下標 if(who<0) //說明id賬戶不存在 { printf("該使用者不存在,修改密碼失敗!\n"); } else { printf("戶主姓名:%s\n", name[who]); printf("密碼:"); iPass=inputPassword(); if(iPass!=user[who][1]) { printf("輸入密碼錯誤,不能繼續操作!\n"); } else { printf("新密碼:"); iPass1=inputPassword(); //輸入密碼1 printf("確認密碼:"); iPass2=inputPassword(); //輸入密碼2 if(iPass1==iPass2) { user[who][1]=iPass1; printf("修改成功!\n"); } else { printf("兩次輸入不同,修改失敗!\n"); } } } return; } /* 功能:輸入密碼 返回值:整型的密碼值 技術說明: (1)此功能在多個模組中都要用到且功能單一,故分離出來,單獨作業一個函式 (2)為了便於在輸入中只顯示*,接受輸入時以字元形式輸入,而後轉為對應的整型數 (3)規定密碼由不全為0的6位數字構成(當開頭是'0'時,實際不足6位),一旦輸入錯誤將重新輸入 附:在實際的系統中,密碼通常用字串描述,即使只允許出現數字字元 */ 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; } /* 功能:根據賬號查詢使用者,返回使用者的下標 入口引數:要查詢使用者的賬號 返回值:如果該使用者存在,返回該使用者在陣列中的下標,否則,返回一個負數(-1) 說明: 由於不能保證在user陣列中按賬號有序,本模組不得不採用順序查詢,這是一個效率很低的演算法 如果在開戶模組中保證了按賬號有序,本函式可以選擇更快的演算法(見開戶模組的說明) */ int search(int id) { int index=-1; int i; for(i=0; i<N; i++) { if(user[i][0]==id) { index=i; break; //找到了,立即退出迴圈 } } return index; //若找到,其值在0~N-1間,否則,保持-1 }
password.txt中的內容:
Boss 123456
相關推薦
C語言及程式設計進階例程-2 一個程式,多個檔案
演示:建立多檔案的專案main.c#include <stdio.h> int max(int x,int y); int main( ) { int a,b,c; printf("輸入兩數:"); scanf("%d %d", &a, &b
C語言及程式設計初步例程-26 利用switch語句解決問題
應用:計算運費每公里每噸貨物的基本運費為p(price),貨物重為w(weight),距離為s,折扣為d(discount),則總運費f(freight)的計算公式為 freight=price*wei
C語言及程式設計初步例程-42 將資料輸出到文字檔案
檔案的操作步驟#include <stdio.h> #include <stdlib.h> int main() { FILE *fp; int i, d;
C語言及程式設計初步例程-25 用switch語句實現多分支結構
例:這是星期幾?#include <stdio.h> int main() { int week; scanf("%d", &week); switch(we
C語言及程式設計 實踐參考 迴圈的巢狀流程圖
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
C語言及程式設計 實踐參考 分段函式求值switch語句版
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
C語言及程式設計 實踐參考——個人所得稅計算器if語句版
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
C語言及程式設計 實踐參考——定期存款利息計算器
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
C語言及程式設計 實踐參考 迴圈的巢狀流程圖
迴圈的巢狀流程圖(1)求s=1!+2!+……10!,即求1到10的階乘和[參考解答]或者: (2)求s=1+2^2+3^3+4^4+5^5+6^6,要求n^n不能用求冪的運算直接計算(n^n表示n的n次方)[參考解答]
教你徹底學會c語言動態規劃——進階篇
今天小編給大家帶來了c語言動態規劃的進階篇。溫馨提示:亮點在最後! 如果想學c++並想學好,可以加這個群,首先是玖四捌,中間是玖伍四,最後是四捌四,裡面有大量的學習資料可以下載。 在我的上一篇文章中已經詳細講解了動態規劃的原理和如何使用動態規劃解題。本篇文章,我將繼續
《C語言及程式設計》實踐專案——利用switch語句解決問題
【專案1:投票表決器】設計一個投票表決器,其功能是:輸入Y、y,列印agree輸入N、n,列印disagree輸入其他,列印lose請在下面程式碼的基礎上,將程式補充完整#include <stdio.h> int main( ) { char c;
《C語言及程式設計》程式閱讀——三種迴圈語句
讀程式,寫出執行結果,並與計算機執行的結果進行對照(1)#include <stdio.h> int main( ) { char c1,c2; for(c1='0',c
《C語言及程式設計》實踐參考——二分法解方程
【專案2-二分法解方程】 二分法是在電腦科學中很重要的一種方法,用於查詢產生二分查詢演算法,還可以用在很多場合。 可以用二分法解方程。 對於區間[a,b]上連續不斷且f(a)·f(b)<0的
《C語言及程式設計初步》-07分支結構程式設計體驗
07分支結構程式設計體驗 【專案1-正差值】 給定兩個正整數,求出兩數的正差值並輸出。 樣例輸入 樣例輸出 7 10 3 12 7 5 /* [cpp] Program 0702 【專案1-正差值】 *Copyright (c)2016,賀立堅
《C語言及程式設計》實踐參考——迴圈的巢狀流程圖
迴圈的巢狀流程圖(1)求s=1!+2!+……10!,即求1到10的階乘和[參考解答]或者: (2)求s=1+2^2+3^3+4^4+5^5+6^6,要求n^n不能用求冪的運算直接計算(n^n表示n的n次
《C語言及程式設計》資料——C語言中轉義字元
下面是C語言中的轉義字元及其意義:轉義字元意義ASCII碼值(十進位制)\a響鈴(BEL)007\b退格(BS) ,將當前位置移到前一列008\f換頁(FF),將當前位置移到下頁開頭012\n換行(LF
《C語言及程式設計》實踐專案——一維陣列初步
【專案1 - 陣列大折騰】(1)建立一個有20個元素的整型陣列,通過初始化,為陣列中的前10個元素賦初值,然後通過鍵盤輸入後10個元素的值,從前往後(從第0個到第19個)輸出陣列中元素的值,每5個元素換一行。int main( ) { int a[20]={...};
《C語言及程式設計》實踐專案——二維陣列與指標
【專案1-二維陣列當函式引數】定義一個函式來完成對引數陣列中元素的求和工作,函式宣告如下:int sum(int array[ ][4],int m,int n); //該函式完成對array陣列中的前m行和n列元素求和在以下程式的基礎上,完成對sum函式的定義。#include <stdio.h&g
《C語言及程式設計》實踐參考——三色球問題
【專案6-三色球問題】若一個口袋中放有12個球,其中有3個紅的。3個白的和6個黒的,問從中任取8個共有多少種不同的顏色搭配?提示:設任取的紅球個數為i,白球個數為j,則黒球個數為8-i-j,根據題意紅球
《C語言及程式設計》實踐參考——矩陣運算
【專案2-矩陣運算】 在數學中,一個矩陣由若干行和若干列資料組成,可以直接儲存為一個二維陣列。(1)矩陣相加 兩個矩陣相加,要求其行、列數均相等。運算規則為:一個n行m列的矩陣A加上另一個n行m列的