【C语言】银行账户管理系统丨源码+解析

系统功能说明

1. 核心功能模块

  • 账户管理:创建/删除账户,自动生成唯一账号
  • 资金操作:存款/取款/转账(含余额校验)
  • 账户服务:余额查询/密码修改/交易记录查询
  • 数据持久化:文件存储所有账户信息

2. 关键技术实现

3. 数据结构设计

字段 类型 说明
accountID char[20] 唯一账户标识
name char[50] 客户姓名
password char[20] 加密密码
balance double 账户余额
transactions char[100][50] 交易记录缓存
transactionCount int 交易记录数

4. 安全特性

  1. 密码加密输入 :使用_getch()实现密码星号显示
  2. 余额验证:取款/转账前检查余额充足性
  3. 交易审计:记录最近50笔交易
  4. 操作确认:关键操作前要求二次确认

5. 文件存储机制

  • 二进制存储 :使用fwrite/fread高效读写
  • 数据完整性:保存账户数和下一个可用ID
  • 自动加载:程序启动时自动恢复数据

编译运行说明

  1. 开发环境:Visual Studio 2019 (需安装C++桌面开发组件)
  2. 创建项目
    • 新建"控制台应用"项目
    • 将代码粘贴到main.c文件中
  3. 注意事项
    • 密码输入时显示星号(*)
    • 数据存储在程序同目录的accounts.dat文件
    • 初始账户ID从10001开始自动递增

扩展建议

  1. 增加利息计算:实现按日计息功能
  2. 多账户管理:支持同一客户多个账户
  3. 管理员模式:添加账户冻结/解冻功能
  4. 数据加密:使用简单异或加密保护密码
  5. 界面优化:添加颜色和ASCII艺术字

系统完整实现了银行核心业务流程,通过文件存储保证数据持久化,交易记录功能便于审计,适合作为C语言文件操作和结构体应用的实践案例

源码

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>  // 密码输入处理
#include <ctype.h>  // 字符处理

#define MAX_ACCOUNTS 100
#define FILENAME "accounts.dat"
#define TRANSACTION_HISTORY_SIZE 50

// 账户结构体
typedef struct {
    char accountID[20];      // 账号
    char name[50];           // 姓名
    char password[20];       // 密码
    double balance;          // 余额
    char transactions[TRANSACTION_HISTORY_SIZE][100]; // 交易记录
    int transactionCount;    // 交易计数
} Account;

Account accounts[MAX_ACCOUNTS];
int accountCount = 0;
int nextAccountID = 10001;   // 初始账号

// 函数声明
void loadAccounts();
void saveAccounts();
void createAccount();
void deleteAccount();
void deposit();
void withdraw();
void transfer();
void checkBalance();
void changePassword();
void viewAccountInfo();
int findAccount(const char* id);
void printHeader();
void clearInputBuffer();

int main() {
    loadAccounts(); // 启动时加载账户数据
    
    while (1) {
        system("cls");
        printHeader();
        printf("\n\t银行账户管理系统\n");
        printf("\t====================\n");
        printf("\t1. 创建账户\n");
        printf("\t2. 存款\n");
        printf("\t3. 取款\n");
        printf("\t4. 转账\n");
        printf("\t5. 查询余额\n");
        printf("\t6. 修改密码\n");
        printf("\t7. 账户信息\n");
        printf("\t8. 删除账户\n");
        printf("\t0. 退出系统\n");
        printf("\t====================\n");
        printf("\t请选择操作: ");
        
        int choice;
        if (scanf("%d", &choice) != 1) {
            clearInputBuffer();
            continue;
        }
        
        switch (choice) {
            case 1: createAccount(); break;
            case 2: deposit(); break;
            case 3: withdraw(); break;
            case 4: transfer(); break;
            case 5: checkBalance(); break;
            case 6: changePassword(); break;
            case 7: viewAccountInfo(); break;
            case 8: deleteAccount(); break;
            case 0: 
                saveAccounts();
                printf("\n\t系统已保存数据,感谢使用!\n");
                exit(0);
            default:
                printf("\n\t无效选择,请重新输入!\n");
        }
        printf("\n\t按任意键继续...");
        _getch();
    }
    return 0;
}

// 加载账户数据
void loadAccounts() {
    FILE* file = fopen(FILENAME, "rb");
    if (file) {
        fread(&nextAccountID, sizeof(int), 1, file);
        fread(&accountCount, sizeof(int), 1, file);
        fread(accounts, sizeof(Account), accountCount, file);
        fclose(file);
    }
}

// 保存账户数据
void saveAccounts() {
    FILE* file = fopen(FILENAME, "wb");
    if (file) {
        fwrite(&nextAccountID, sizeof(int), 1, file);
        fwrite(&accountCount, sizeof(int), 1, file);
        fwrite(accounts, sizeof(Account), accountCount, file);
        fclose(file);
    }
}

// 创建新账户
void createAccount() {
    system("cls");
    printHeader();
    printf("\n\t--- 创建新账户 ---\n");
    
    if (accountCount >= MAX_ACCOUNTS) {
        printf("\n\t账户数量已达上限!\n");
        return;
    }
    
    Account newAcc;
    sprintf(newAcc.accountID, "%d", nextAccountID++);
    newAcc.transactionCount = 0;
    newAcc.balance = 0.0;
    
    printf("\n\t请输入姓名: ");
    scanf("%s", newAcc.name);
    
    // 密码输入(带*号显示)
    printf("\t设置密码: ");
    int i = 0;
    char ch;
    while ((ch = _getch()) != '\r' && i < 19) {
        if (ch == '\b' && i > 0) {
            printf("\b \b");
            i--;
        } else if (isprint(ch)) {
            newAcc.password[i++] = ch;
            printf("*");
        }
    }
    newAcc.password[i] = '\0';
    printf("\n");
    
    // 初始存款
    double initDeposit;
    printf("\n\t请输入初始存款金额: ");
    scanf("%lf", &initDeposit);
    
    if (initDeposit < 10.0) {
        printf("\n\t初始存款不能低于10元!\n");
        return;
    }
    
    newAcc.balance = initDeposit;
    
    // 记录初始交易
    char trans[100];
    sprintf(trans, "开户存入: %.2f元", initDeposit);
    strcpy(newAcc.transactions[newAcc.transactionCount++], trans);
    
    accounts[accountCount++] = newAcc;
    printf("\n\t账户创建成功!账号: %s\n", newAcc.accountID);
}

// 存款操作
void deposit() {
    system("cls");
    printHeader();
    printf("\n\t--- 存款操作 ---\n");
    
    char id[20];
    printf("\n\t请输入账号: ");
    scanf("%s", id);
    
    int index = findAccount(id);
    if (index == -1) {
        printf("\n\t账户不存在!\n");
        return;
    }
    
    // 密码验证
    char pwd[20];
    printf("\t请输入密码: ");
    int i = 0;
    char ch;
    while ((ch = _getch()) != '\r' && i < 19) {
        if (ch == '\b' && i > 0) {
            printf("\b \b");
            i--;
        } else if (isprint(ch)) {
            pwd[i++] = ch;
            printf("*");
        }
    }
    pwd[i] = '\0';
    
    if (strcmp(accounts[index].password, pwd) != 0) {
        printf("\n\n\t密码错误!\n");
        return;
    }
    
    double amount;
    printf("\n\n\t请输入存款金额: ");
    scanf("%lf", &amount);
    
    if (amount <= 0) {
        printf("\n\t存款金额必须大于0!\n");
        return;
    }
    
    accounts[index].balance += amount;
    
    // 记录交易
    char trans[100];
    sprintf(trans, "存款: %.2f元", amount);
    if (accounts[index].transactionCount < TRANSACTION_HISTORY_SIZE) {
        strcpy(accounts[index].transactions[accounts[index].transactionCount++], trans);
    } else {
        // 循环覆盖旧记录
        for (int i = 0; i < TRANSACTION_HISTORY_SIZE - 1; i++) {
            strcpy(accounts[index].transactions[i], accounts[index].transactions[i + 1]);
        }
        strcpy(accounts[index].transactions[TRANSACTION_HISTORY_SIZE - 1], trans);
    }
    
    printf("\n\t存款成功!当前余额: %.2f元\n", accounts[index].balance);
}

// 取款操作
void withdraw() {
    system("cls");
    printHeader();
    printf("\n\t--- 取款操作 ---\n");
    
    char id[20];
    printf("\n\t请输入账号: ");
    scanf("%s", id);
    
    int index = findAccount(id);
    if (index == -1) {
        printf("\n\t账户不存在!\n");
        return;
    }
    
    // 密码验证
    char pwd[20];
    printf("\t请输入密码: ");
    int i = 0;
    char ch;
    while ((ch = _getch()) != '\r' && i < 19) {
        if (ch == '\b' && i > 0) {
            printf("\b \b");
            i--;
        } else if (isprint(ch)) {
            pwd[i++] = ch;
            printf("*");
        }
    }
    pwd[i] = '\0';
    
    if (strcmp(accounts[index].password, pwd) != 0) {
        printf("\n\n\t密码错误!\n");
        return;
    }
    
    double amount;
    printf("\n\n\t请输入取款金额: ");
    scanf("%lf", &amount);
    
    if (amount <= 0) {
        printf("\n\t取款金额必须大于0!\n");
        return;
    }
    
    if (amount > accounts[index].balance) {
        printf("\n\t余额不足!当前余额: %.2f元\n", accounts[index].balance);
        return;
    }
    
    accounts[index].balance -= amount;
    
    // 记录交易
    char trans[100];
    sprintf(trans, "取款: %.2f元", amount);
    if (accounts[index].transactionCount < TRANSACTION_HISTORY_SIZE) {
        strcpy(accounts[index].transactions[accounts[index].transactionCount++], trans);
    } else {
        // 循环覆盖旧记录
        for (int i = 0; i < TRANSACTION_HISTORY_SIZE - 1; i++) {
            strcpy(accounts[index].transactions[i], accounts[index].transactions[i + 1]);
        }
        strcpy(accounts[index].transactions[TRANSACTION_HISTORY_SIZE - 1], trans);
    }
    
    printf("\n\t取款成功!当前余额: %.2f元\n", accounts[index].balance);
}

// 转账操作
void transfer() {
    system("cls");
    printHeader();
    printf("\n\t--- 转账操作 ---\n");
    
    char fromID[20], toID[20];
    printf("\n\t请输入转出账号: ");
    scanf("%s", fromID);
    
    int fromIndex = findAccount(fromID);
    if (fromIndex == -1) {
        printf("\n\t转出账户不存在!\n");
        return;
    }
    
    // 密码验证
    char pwd[20];
    printf("\t请输入密码: ");
    int i = 0;
    char ch;
    while ((ch = _getch()) != '\r' && i < 19) {
        if (ch == '\b' && i > 0) {
            printf("\b \b");
            i--;
        } else if (isprint(ch)) {
            pwd[i++] = ch;
            printf("*");
        }
    }
    pwd[i] = '\0';
    
    if (strcmp(accounts[fromIndex].password, pwd) != 0) {
        printf("\n\n\t密码错误!\n");
        return;
    }
    
    printf("\n\n\t请输入转入账号: ");
    scanf("%s", toID);
    
    int toIndex = findAccount(toID);
    if (toIndex == -1) {
        printf("\n\t转入账户不存在!\n");
        return;
    }
    
    if (strcmp(fromID, toID) == 0) {
        printf("\n\t不能转账给自己!\n");
        return;
    }
    
    double amount;
    printf("\n\t请输入转账金额: ");
    scanf("%lf", &amount);
    
    if (amount <= 0) {
        printf("\n\t转账金额必须大于0!\n");
        return;
    }
    
    if (amount > accounts[fromIndex].balance) {
        printf("\n\t余额不足!当前余额: %.2f元\n", accounts[fromIndex].balance);
        return;
    }
    
    // 执行转账
    accounts[fromIndex].balance -= amount;
    accounts[toIndex].balance += amount;
    
    // 记录转出交易
    char fromTrans[100];
    sprintf(fromTrans, "转出到%s: %.2f元", toID, amount);
    if (accounts[fromIndex].transactionCount < TRANSACTION_HISTORY_SIZE) {
        strcpy(accounts[fromIndex].transactions[accounts[fromIndex].transactionCount++], fromTrans);
    } else {
        for (int i = 0; i < TRANSACTION_HISTORY_SIZE - 1; i++) {
            strcpy(accounts[fromIndex].transactions[i], accounts[fromIndex].transactions[i + 1]);
        }
        strcpy(accounts[fromIndex].transactions[TRANSACTION_HISTORY_SIZE - 1], fromTrans);
    }
    
    // 记录转入交易
    char toTrans[100];
    sprintf(toTrans, "从%s转入: %.2f元", fromID, amount);
    if (accounts[toIndex].transactionCount < TRANSACTION_HISTORY_SIZE) {
        strcpy(accounts[toIndex].transactions[accounts[toIndex].transactionCount++], toTrans);
    } else {
        for (int i = 0; i < TRANSACTION_HISTORY_SIZE - 1; i++) {
            strcpy(accounts[toIndex].transactions[i], accounts[toIndex].transactions[i + 1]);
        }
        strcpy(accounts[toIndex].transactions[TRANSACTION_HISTORY_SIZE - 1], toTrans);
    }
    
    printf("\n\t转账成功!当前余额: %.2f元\n", accounts[fromIndex].balance);
}

// 查询余额
void checkBalance() {
    system("cls");
    printHeader();
    printf("\n\t--- 查询余额 ---\n");
    
    char id[20];
    printf("\n\t请输入账号: ");
    scanf("%s", id);
    
    int index = findAccount(id);
    if (index == -1) {
        printf("\n\t账户不存在!\n");
        return;
    }
    
    // 密码验证
    char pwd[20];
    printf("\t请输入密码: ");
    int i = 0;
    char ch;
    while ((ch = _getch()) != '\r' && i < 19) {
        if (ch == '\b' && i > 0) {
            printf("\b \b");
            i--;
        } else if (isprint(ch)) {
            pwd[i++] = ch;
            printf("*");
        }
    }
    pwd[i] = '\0';
    
    if (strcmp(accounts[index].password, pwd) != 0) {
        printf("\n\n\t密码错误!\n");
        return;
    }
    
    printf("\n\n\t账户: %s\n", accounts[index].accountID);
    printf("\t姓名: %s\n", accounts[index].name);
    printf("\t当前余额: %.2f元\n", accounts[index].balance);
}

// 修改密码
void changePassword() {
    system("cls");
    printHeader();
    printf("\n\t--- 修改密码 ---\n");
    
    char id[20];
    printf("\n\t请输入账号: ");
    scanf("%s", id);
    
    int index = findAccount(id);
    if (index == -1) {
        printf("\n\t账户不存在!\n");
        return;
    }
    
    // 原密码验证
    char oldPwd[20];
    printf("\t请输入原密码: ");
    int i = 0;
    char ch;
    while ((ch = _getch()) != '\r' && i < 19) {
        if (ch == '\b' && i > 0) {
            printf("\b \b");
            i--;
        } else if (isprint(ch)) {
            oldPwd[i++] = ch;
            printf("*");
        }
    }
    oldPwd[i] = '\0';
    
    if (strcmp(accounts[index].password, oldPwd) != 0) {
        printf("\n\n\t原密码错误!\n");
        return;
    }
    
    // 新密码设置
    char newPwd[20];
    printf("\n\n\t请输入新密码: ");
    i = 0;
    while ((ch = _getch()) != '\r' && i < 19) {
        if (ch == '\b' && i > 0) {
            printf("\b \b");
            i--;
        } else if (isprint(ch)) {
            newPwd[i++] = ch;
            printf("*");
        }
    }
    newPwd[i] = '\0';
    
    // 确认新密码
    char confirmPwd[20];
    printf("\n\t请确认新密码: ");
    i = 0;
    while ((ch = _getch()) != '\r' && i < 19) {
        if (ch == '\b' && i > 0) {
            printf("\b \b");
            i--;
        } else if (isprint(ch)) {
            confirmPwd[i++] = ch;
            printf("*");
        }
    }
    confirmPwd[i] = '\0';
    
    if (strcmp(newPwd, confirmPwd) != 0) {
        printf("\n\n\t两次输入密码不一致!\n");
        return;
    }
    
    strcpy(accounts[index].password, newPwd);
    printf("\n\n\t密码修改成功!\n");
}

// 查看账户信息
void viewAccountInfo() {
    system("cls");
    printHeader();
    printf("\n\t--- 账户信息 ---\n");
    
    char id[20];
    printf("\n\t请输入账号: ");
    scanf("%s", id);
    
    int index = findAccount(id);
    if (index == -1) {
        printf("\n\t账户不存在!\n");
        return;
    }
    
    // 密码验证
    char pwd[20];
    printf("\t请输入密码: ");
    int i = 0;
    char ch;
    while ((ch = _getch()) != '\r' && i < 19) {
        if (ch == '\b' && i > 0) {
            printf("\b \b");
            i--;
        } else if (isprint(ch)) {
            pwd[i++] = ch;
            printf("*");
        }
    }
    pwd[i] = '\0';
    
    if (strcmp(accounts[index].password, pwd) != 0) {
        printf("\n\n\t密码错误!\n");
        return;
    }
    
    printf("\n\n\t账户信息:\n");
    printf("\t账号: %s\n", accounts[index].accountID);
    printf("\t姓名: %s\n", accounts[index].name);
    printf("\t余额: %.2f元\n", accounts[index].balance);
    
    if (accounts[index].transactionCount > 0) {
        printf("\n\t最近交易记录:\n");
        int start = accounts[index].transactionCount > 5 ? 
            accounts[index].transactionCount - 5 : 0;
        
        for (int i = start; i < accounts[index].transactionCount; i++) {
            printf("\t%d. %s\n", i + 1, accounts[index].transactions[i]);
        }
    } else {
        printf("\n\t暂无交易记录\n");
    }
}

// 删除账户
void deleteAccount() {
    system("cls");
    printHeader();
    printf("\n\t--- 删除账户 ---\n");
    
    char id[20];
    printf("\n\t请输入要删除的账号: ");
    scanf("%s", id);
    
    int index = findAccount(id);
    if (index == -1) {
        printf("\n\t账户不存在!\n");
        return;
    }
    
    // 密码验证
    char pwd[20];
    printf("\t请输入密码: ");
    int i = 0;
    char ch;
    while ((ch = _getch()) != '\r' && i < 19) {
        if (ch == '\b' && i > 0) {
            printf("\b \b");
            i--;
        } else if (isprint(ch)) {
            pwd[i++] = ch;
            printf("*");
        }
    }
    pwd[i] = '\0';
    
    if (strcmp(accounts[index].password, pwd) != 0) {
        printf("\n\n\t密码错误!\n");
        return;
    }
    
    // 确认删除
    char confirm;
    printf("\n\n\t确定要删除账户 %s 吗?(y/n): ", id);
    scanf(" %c", &confirm);
    
    if (confirm == 'y' || confirm == 'Y') {
        // 移动数组元素
        for (int i = index; i < accountCount - 1; i++) {
            accounts[i] = accounts[i + 1];
        }
        accountCount--;
        printf("\n\t账户删除成功!\n");
    } else {
        printf("\n\t已取消删除操作\n");
    }
}

// 查找账户索引
int findAccount(const char* id) {
    for (int i = 0; i < accountCount; i++) {
        if (strcmp(accounts[i].accountID, id) == 0) {
            return i;
        }
    }
    return -1;
}

// 打印表头
void printHeader() {
    printf("\n================================================");
    printf("\n=            银行账户管理系统 (VS2019)         =");
    printf("\n================================================\n");
}

// 清除输入缓冲区
void clearInputBuffer() {
    while (getchar() != '\n');
}
相关推荐
剪一朵云爱着4 小时前
力扣面试题 17.05. 字母与数字
算法·leetcode
虾球xz4 小时前
CppCon 2016 学习:GAME ENGINE USING C++11
大数据·开发语言·c++·学习
虾球xz5 小时前
CppCon 2016 学习:fixed_point Library
开发语言·c++·学习
code喵喵5 小时前
八种数据结构简介
数据结构·算法·推荐算法
HaiQinyanAN5 小时前
【学习笔记】nlohmannjson&&cjson
c++·笔记·学习·json
wen__xvn5 小时前
九日集训第三天
数据结构·算法·leetcode
嵌引工坊6 小时前
Proteus如何创建第一个工程
c语言·单片机·嵌入式硬件·测试工具·proteus
dying_man6 小时前
LeetCode--33.搜索旋转排序数组
算法·leetcode
东方芷兰6 小时前
Leetcode 刷题记录 17 —— 堆
java·c++·b树·算法·leetcode·职场和发展