Windows下Replit中C程序登录时‘打开登录文件失败’问题排查
登录文件打开错误问题排查与解决
问题概述
在Windows系统的Replit平台开发一款支持管理/购买两种模式的C语言登录程序,登录时触发「Error opening login file」错误,添加调试语句后问题仍未解决。
完整代码
typedef struct{ char name[50]; char lname[50]; char id[50]; char password[50]; int isSignedIn; int mode; }Login; void logorsignin(Login *a, int mode) { int login; char id[50]; char password[50]; char name[50]; char lname[50]; char sid[50]; char spassword[50]; int r = 0; int choix; printf("\nHello\n"); printf("1. Login\n"); printf("2. Sign up\n"); printf("3. Back\n"); scanf("%d", &login); switch (login) { case 1: printf("What is your id?\n"); scanf("%s", id); printf("What is your password?\n"); scanf("%s", password); FILE *fichier_login; if (mode == 1) { fichier_login = fopen("idandpasswordManagement.txt", "r"); } else if (mode == 2) { fichier_login = fopen("idandpasswordBuying.txt", "r"); } if (fichier_login == NULL) { printf("Error opening login file.\n"); exit(1); } else { while (fscanf(fichier_login, "%s %s %s %s", a->name, a->lname, a->id, a->password) != EOF) { if (strcmp(id, a->id) == 0 && strcmp(password, a->password) == 0) { printf("You are connected\n"); r = 1; a->isSignedIn = 1; a->mode = mode; // Store the chosen mode in the Login struct break; } } if (r != 1) { printf("Your id or your password is incorrect\n"); a->isSignedIn = 0; } } fclose(fichier_login); break; case 2: printf("What is your first name?\n"); scanf("%s", name); printf("What is your last name?\n"); scanf("%s", lname); printf("Choose an id\n"); scanf("%s", sid); printf("Choose a password\n"); scanf("%s", spassword); // Ask for the mode during sign-up printf("Choose your mode:\n"); printf("1. Management\n"); printf("2. Buying\n"); scanf("%d", &mode); FILE *fichier_signup; if (mode == 1) { fichier_signup = fopen("idandpasswordManagement.txt", "a"); } else if (mode == 2) { fichier_signup = fopen("idandpasswordBuying.txt", "a"); } if (fichier_signup == NULL) { printf("Error opening signup file.\n"); exit(1); } else { fprintf(fichier_signup, "\n%s %s %s %s", name, lname, sid, spassword); fclose(fichier_signup); a->isSignedIn = 1; printf("Sign up successful. You are now signed in.\n"); a->mode = mode; // Store the chosen mode in the Login struct } break; case 3: printf("Going back...\n"); return; default: printf("Error: Choose a correct option.\n"); break; } } int main(void) { int choice; printf("\n WELCOME TO UTOPIA !\n\n"); Login a; logorsignin(&a,a.mode); if (a.isSignedIn == 1) { if (a.mode == 1) { // Management mode printf("MANAGEMENT"); } else if (a.mode == 2) { // Buying mode printf("BUYING"); } } return 0; }
关键代码片段
登录时的文件打开逻辑
FILE *fichier_login; if (mode == 1) { fichier_login = fopen("idandpasswordManagement.txt", "r"); } else if (mode == 2) { fichier_login = fopen("idandpasswordBuying.txt", "r"); } if (fichier_login == NULL) { printf("Error opening login file.\n"); exit(1); }
添加调试后的文件打开逻辑
FILE *fichier_login; if (mode == 1) { printf("Opening login file (idandpasswordManagement.txt)...\n"); fichier_login = fopen("idandpasswordManagement.txt", "r"); if (fichier_login == NULL) { printf("Error opening login file (idandpasswordManagement.txt).\n"); exit(1); } } else if (mode == 2) { printf("Opening login file (idandpasswordBuying.txt)...\n"); fichier_login = fopen("idandpasswordBuying.txt", "r"); if (fichier_login == NULL) { printf("Error opening login file (idandpasswordBuying.txt).\n"); exit(1); } }
问题原因分析
- 未初始化的mode参数:main函数中声明的
Login a是局部变量,其mode成员未被初始化,值为随机垃圾值。调用logorsignin(&a,a.mode)时,传入的mode既不是1也不是2,导致文件打开的两个分支都不执行,fichier_login成为野指针,触发NULL判断错误。 - Replit平台的文件路径问题:Replit的沙箱环境工作目录可能与预期不符,即使注册时成功创建文件,登录时相对路径无法定位到目标文件。
- 缺失非法mode的处理逻辑:当传入的mode不是1或2时,没有对应的错误提示,直接进入NULL判断,导致错误信息不精准。
解决方案建议
1. 修复mode参数初始化问题
在main函数中,先让用户选择合法的模式后再调用登录/注册函数,避免传递未初始化的参数:
int main(void) { int choice; printf("\n WELCOME TO UTOPIA !\n\n"); Login a; // 先选择模式 printf("Choose your mode:\n1. Management\n2. Buying\n"); scanf("%d", &a.mode); // 校验输入合法性 while(a.mode != 1 && a.mode != 2){ printf("Invalid input! Please choose 1 or 2:\n"); scanf("%d", &a.mode); } logorsignin(&a,a.mode); if (a.isSignedIn == 1) { if (a.mode == 1) { printf("MANAGEMENT"); } else if (a.mode == 2) { printf("BUYING"); } } return 0; }
或者在登录分支中,让用户重新选择模式,覆盖传入的参数:
case 1: // 先选择模式 printf("Choose your mode:\n1. Management\n2. Buying\n"); scanf("%d", &mode); while(mode !=1 && mode !=2){ printf("Invalid input! Please choose 1 or 2:\n"); scanf("%d", &mode); } // 后续文件打开逻辑...
2. 确认Replit的文件路径
- 添加代码打印当前工作目录,确认文件位置:
#include <direct.h> // Windows环境头文件 // 在登录分支前添加 char cwd[1024]; if (_getcwd(cwd, sizeof(cwd)) != NULL) { printf("Current working directory: %s\n", cwd); }
- 注册成功后,检查Replit项目的文件列表,确认文件是否在当前工作目录下。若不在,调整fopen的路径为绝对路径,或使用
"./idandpasswordManagement.txt"明确相对路径。
3. 增强错误处理逻辑
添加非法mode的判断分支,避免野指针:
FILE *fichier_login = NULL; if (mode == 1) { fichier_login = fopen("idandpasswordManagement.txt", "r"); } else if (mode == 2) { fichier_login = fopen("idandpasswordBuying.txt", "r"); } else { printf("Invalid mode selected! Please choose 1 or 2.\n"); exit(1); } if (fichier_login == NULL) { printf("Error opening login file.\n"); exit(1); }
内容的提问来源于stack exchange,提问作者Firas
相关产品推荐
相关产品推荐

