系統架構
- User 結構體:帳號、密碼、餘額、next 指標構成單向鏈表;
- 檔案層:啟動讀取
Account.txt 建立鏈表,退出時覆寫存盤;
- 業務層:查帳、驗密、存款、取款、改密、掛失;
- 介面層:主選單、金額選單、密碼輸入遮罩、清屏刷新。
核心資料結構
struct User {
char UserAccount[100];
char UserPassword[100];
int Money;
struct User *next;
};
struct User *head = NULL, *Current_user = NULL;
關鍵功能實現片段
檔案初始化與持久化
void initdata(FILE *fp, char *path) {
if (fopen_s(&fp, path, "r+") == 0 && fgetc(fp) == EOF) {
// 首次運行,寫入預設測試帳號
fprintf(fp, "6210300022352323 123123 10000\n");
// ... 共 5 筆
}
rewind(fp);
while (fscanf_s(fp, "%s %s %d", u->UserAccount, u->UserPassword, &u->Money) != EOF) {
// 建立鏈表節點掛入 head
}
fclose(fp);
}
void writeIntoFile(FILE *fp, char *path) {
fopen_s(&fp, path, "w+");
for (struct User *p = head; p; p = p->next)
fprintf(fp, "%s %s %d\n", p->UserAccount, p->UserPassword, p->Money);
fclose(fp);
}
帳戶驗證與操作選單
bool checkAccount(char *acc, struct User **out) {
for (struct User *p = head; p; p = p->next)
if (strncmp(p->UserAccount, acc, 16) == 0) { *out = p; return true; }
return false;
}
void OperationMenu() {
char menu[5][20] = {"取款","存款","查詢餘額","修改密碼","退卡"};
showMenu(menu, 5);
switch (_getch()) {
case '1': WithDraw(SelectMoney()); break;
case '2': Deposit(SelectMoney()); break;
case '3': printf("餘額:%d\n", Current_user->Money); break;
case '4': /* 修改密碼雙重確認 */ break;
case '5': return; // 退卡觸發存檔
}
_getch(); OperationMenu(); // 遞歸回選單
}
金額輸入與選單
int SelectMoney() {
char menu[5][20] = {"100","200","500","1000","輸入金額"};
showMenu(menu, 5);
switch (_getch()) {
case '1': return 100;
case '2': return 200;
case '3': return 500;
case '4': return 1000;
case '5': return InputMoney(); // 手動輸入,上限 5000
}
return 0;
}
編譯與執行
gcc Main.cpp User.h UI.h AccountController.h FileController.h -o atm
./atm
設計亮點
- 鏈表動態管理用戶,無固定上限;
- 檔案採用純文字格式,便於人工檢查/備份;
- 介面與業務分離,易於擴充 GUI 或網路版本;
- 密碼輸入即時遮罩(*),支援退格修正。