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
相关产品推荐
相关产品推荐

