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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 10:01:03