You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言ATM机程序find_account_no函数异常问题排查求助

问题排查:C语言ATM程序find_account_no函数异常

我编写了一个具备创建账户、查询余额、交易等功能的基础C语言ATM机程序,采用文件存储账户数据。其中write_account(创建新账户)、read_accounts(读取账户数据)、no_of_accounts(获取账户总数)函数均运行正常,但find_account_no函数(接收账号参数并返回其所在数组索引)出现异常,输出不符合预期。以下是完整代码:

#include <stdio.h>
#include <stdlib.h>

#define MAX_act 100 
typedef struct{
    long account_number;
    int CVV;
    int PIN;
    float balance;
    long phone_number;
} act;

void write_account(long account_number, int CVV, int PIN, long phone_number)
{
    FILE *f;
    act *account = (act*) malloc(sizeof(act));
    f = fopen("account_data", "a");
    *account = (act) { account_number, CVV, PIN, 0, phone_number};
    fprintf(f, "%ld %d %d %.2f %ld\n", account->account_number, account->CVV, account->PIN, account->balance, account->phone_number);
    fclose(f);
}

act* read_accounts(void){
    FILE *f;
    int i = 0;
    f = fopen("account_data", "r");
    act *accounts = (act*) malloc(sizeof(act)*MAX_act);
    while(fscanf(f, "%ld %d %d %f %ld", &accounts[i].account_number, &accounts[i].CVV, &accounts[i].PIN, &accounts[i].balance, &accounts[i].phone_number) == 5){
    i++;
    }
    fclose(f);
    return accounts;
}

int no_of_accounts(void){
    FILE *f;
    int i = 0;
    act *accounts;
    f = fopen("account_data", "r");
    while(fscanf(f, "%ld %d %d %f %ld", &accounts->account_number, &accounts->CVV, &accounts->PIN, &accounts->balance, &accounts->phone_number) == 5)
    i++;
    free(accounts);
    return i;
}

int find_account_no(long account_number, int no_of_accounts, act *accounts){
    int i = 0;
    act *account = accounts;
    printf("yes, it's called\n");
    for(i=0; i< no_of_accounts; i++){
        printf("%ld\n", account[i].account_number);
        if(account[i].account_number == account_number)
        return i;
    }
    return -1;
}


int main(){
    //write_account(123, 111, 222, 939);
    //write_account(321, 111, 222, 939);
    //write_account(123, 111, 222, 939);

    find_account_no(123, no_of_accounts(), read_accounts());
    printf("%d\n", no_of_accounts());
}

问题根源及修复方案

1. no_of_accounts函数的致命内存错误

no_of_accounts中声明了act *accounts;但未初始化,直接通过&accounts->account_number给fscanf传参,属于访问未分配内存的未定义行为,会导致程序崩溃或返回错误的账户数量。

修复代码:

int no_of_accounts(void){
    FILE *f;
    int i = 0;
    act temp_account; // 用单个栈变量临时存储读取的数据
    f = fopen("account_data", "r");
    if(f == NULL) return 0; // 增加文件打开失败的容错判断
    while(fscanf(f, "%ld %d %d %f %ld", &temp_account.account_number, &temp_account.CVV, &temp_account.PIN, &temp_account.balance, &temp_account.phone_number) == 5)
        i++;
    fclose(f);
    return i;
}

2. main函数中调用find_account_no的参数问题

  • C语言函数参数的求值顺序未指定,可能导致read_accounts()和no_of_accounts()的执行顺序不可控,影响查找逻辑。
  • read_accounts()返回的动态分配数组未被保存,调用结束后内存直接泄漏。

修复代码:

int main(){
    //write_account(123, 111, 222, 939);
    //write_account(321, 111, 222, 939);
    //write_account(123, 111, 222, 939);

    int account_count = no_of_accounts();
    act *accounts_list = read_accounts();
    int target_index = find_account_no(123, account_count, accounts_list);
    
    printf("目标账号索引:%d\n", target_index);
    printf("账户总数:%d\n", account_count);
    
    free(accounts_list); // 释放动态分配的内存
    return 0;
}

3. 其他潜在优化点

  • write_account中无需使用malloc,直接用栈上结构体即可:
void write_account(long account_number, int CVV, int PIN, long phone_number)
{
    FILE *f = fopen("account_data", "a");
    if(f == NULL) return;
    act account = { account_number, CVV, PIN, 0, phone_number};
    fprintf(f, "%ld %d %d %.2f %ld\n", account.account_number, account.CVV, account.PIN, account.balance, account.phone_number);
    fclose(f);
}
  • read_accounts需增加文件打开失败的判断,避免空指针操作:
act* read_accounts(void){
    FILE *f = fopen("account_data", "r");
    if(f == NULL) return NULL;
    
    int i = 0;
    act *accounts = (act*) malloc(sizeof(act)*MAX_act);
    while(fscanf(f, "%ld %d %d %f %ld", &accounts[i].account_number, &accounts[i].CVV, &accounts[i].PIN, &accounts[i].balance, &accounts[i].phone_number) == 5){
        i++;
    }
    fclose(f);
    return accounts;
}

内容的提问来源于stack exchange,提问作者valli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 08:07:56