如何实现adminAcc.txt仅初始化一次?程序重复执行仍重复初始化求助
管理员账户初始化重复写入文件的解决方案
你的核心问题是静态全局变量无法跨程序运行保存状态:每次启动程序时,file_initialized都会重新初始化为0,导致每次运行都会执行写入操作;另外用a模式打开文件会追加内容,进一步加剧重复写入的问题。
问题代码回顾
static int file_initialized = 0; //global variable void initAdmin(){ struct form adminAcc; FILE *fptr; if((fptr = fopen("adminAcc.txt", "a")) == NULL){ printf("\nError Opening Admin File!"); getch(); system("cls"); main(); } if(file_initialized != 1){ strcpy(adminAcc.username, "admin@gmail.com"); strcpy(adminAcc.password, "admin"); strcpy(adminAcc.roles, "admin"); fwrite(&adminAcc, sizeof(struct form), 1, fptr); file_initialized = 1; }else{ return; } fclose(fptr); } int main(){ initAdmin(); return 0; }
解决方案:通过文件状态判断是否需要初始化
要实现跨程序运行的初始化判断,必须依赖文件系统的持久化状态,而不是内存中的变量。这里提供两种可靠的实现方式:
方式一:检查目标文件是否已有管理员数据
直接读取adminAcc.txt,尝试读取一条结构体记录,如果成功说明已初始化,否则执行写入:
#include <stdio.h> #include <string.h> #include <conio.h> struct form { char username[50]; char password[50]; char roles[20]; }; void initAdmin(){ struct form adminAcc; FILE *fptr; // 先尝试读取文件,判断是否已有初始化数据 fptr = fopen("adminAcc.txt", "rb"); if (fptr != NULL) { struct form temp; // 尝试读取一条记录,成功则说明已初始化 if (fread(&temp, sizeof(struct form), 1, fptr) == 1) { fclose(fptr); return; } fclose(fptr); } // 文件不存在或无有效数据,执行初始化 fptr = fopen("adminAcc.txt", "wb"); if(fptr == NULL){ printf("\nError Opening Admin File!"); getch(); system("cls"); return; // 避免递归调用main(),防止栈溢出 } strcpy(adminAcc.username, "admin@gmail.com"); strcpy(adminAcc.password, "admin"); strcpy(adminAcc.roles, "admin"); fwrite(&adminAcc, sizeof(struct form), 1, fptr); fclose(fptr); } int main(){ initAdmin(); return 0; }
方式二:使用独立的初始化标记文件
创建一个单独的标记文件(比如init_flag),如果该文件存在则说明已完成初始化:
#include <stdio.h> #include <string.h> #include <conio.h> #include <stdbool.h> struct form { char username[50]; char password[50]; char roles[20]; }; // 判断是否已初始化 bool isInitialized() { FILE *fptr = fopen("init_flag", "r"); if (fptr != NULL) { fclose(fptr); return true; } return false; } // 创建初始化标记 void setInitialized() { FILE *fptr = fopen("init_flag", "w"); if (fptr != NULL) { fclose(fptr); } } void initAdmin(){ if (isInitialized()) { return; } struct form adminAcc; FILE *fptr = fopen("adminAcc.txt", "wb"); if(fptr == NULL){ printf("\nError Opening Admin File!"); getch(); system("cls"); return; } strcpy(adminAcc.username, "admin@gmail.com"); strcpy(adminAcc.password, "admin"); strcpy(adminAcc.roles, "admin"); fwrite(&adminAcc, sizeof(struct form), 1, fptr); fclose(fptr); setInitialized(); } int main(){ initAdmin(); return 0; }
关键改进点
- 移除了依赖内存的静态变量,改用文件系统的持久化状态判断
- 替换
a模式为rb/wb模式,避免追加写入重复数据 - 去掉了递归调用
main()的危险写法,改用直接返回
内容的提问来源于stack exchange,提问作者wanmoranIwhaledye
相关产品推荐
相关产品推荐

