C语言登录系统问题:为何读取整个文件而非逐行校验用户ID?
问题分析与修复方案
你的程序会读完整个文件,主要是这几个问题导致的:
字符串比较逻辑错误:用
loginID == IDcheck比较字符串完全不对,这是在对比两个数组的内存地址,不是字符串内容。哪怕输入的ID和文件里的完全一致,这个判断也永远不会成立,程序自然不会触发登录成功的逻辑,只能一直循环读完整个文件。必须用标准库函数strcmp()来比较字符串,当返回值为0时才表示内容相等。文件结束判断错误:
if (IDcheck == EOF)的写法完全无效,IDcheck是字符数组,EOF是int类型的文件结束标记,两者类型不匹配;而且fgets()读到文件尾时会返回NULL,你的while循环条件已经是fgets(...),所以到文件尾时循环会直接退出,根本不会进入循环体执行这个判断。匹配成功后未终止循环:就算匹配成功的逻辑能触发,你只把
pass1设为1,但没有跳出while循环,程序还是会继续读取剩下的行,直到文件结束。
修复后的代码示例:
#include <string.h> // 引入strcmp、strcspn所需的头文件 int getID() { char loginID[10]; printf("Enter login credentials\nStaff ID:"); scanf("%s", loginID); FILE* file = fopen("Text.txt", "r"); if (!file) { // 增加文件打开失败的判断,避免空指针操作 printf("Failed to open file!"); return 0; } char IDcheck[10]; int pass1 = 0; // 改用局部变量,避免全局变量的副作用 while (fgets(IDcheck, sizeof(IDcheck), file)) { // 去掉fgets读取的换行符,因为文件每行末尾带换行,而输入的loginID没有 IDcheck[strcspn(IDcheck, "\n")] = '\0'; printf("%s\n", IDcheck); if (strcmp(loginID, IDcheck) == 0) { printf("Logged in successfully"); pass1 = 1; break; // 匹配成功后立即跳出循环,停止读取文件 } } if (!pass1) { // 循环结束后统一判断是否找到匹配 printf("Record not found! Enter again!"); } fclose(file); // 记得关闭文件,避免资源泄漏 return pass1; }
额外补充:
fgets()会把每行末尾的换行符也读进数组,必须用strcspn()去掉换行,否则和输入的无换行loginID比较会不相等。- 增加文件打开失败的判断,避免程序因文件不存在/权限问题崩溃。
- 把全局变量
pass1改成局部变量,更符合代码规范,减少全局变量带来的意外问题。
内容的提问来源于stack exchange,提问作者neoh chen lun
相关产品推荐
相关产品推荐

