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

C语言登录系统:输入正确凭证仍触发重新登录问题求助

问题分析与修复方案

核心问题

你的代码触发误判重新登录的关键原因是验证逻辑过于激进:每读取一个用户条目,只要当前条目不匹配就直接调用relogin(),完全跳过了后续用户的校验。比如第一个管理员凭证不对,程序直接触发重新登录,不会继续检查其他管理员或普通员工账号。

除此之外还有几个潜在问题需要修复:


具体问题与修复步骤

  1. 遍历所有用户后再判断是否重新登录
    原代码中,只要单个用户不匹配就立即调用relogin(),正确逻辑应该是遍历完所有目标用户,确认无匹配账号后再触发重新登录。

  2. 替换不安全的输入函数与未定义行为

    • gets()已被C标准废弃,存在缓冲区溢出风险,改用fgets()。
    • fflush(stdin)属于未定义行为,用字符串处理函数清空输入末尾的换行符。
  3. 检查文件打开状态
    若文件不存在或无法读取,fopen()会返回NULL,必须先检查避免后续fread出错。

  4. 匹配成功后终止当前函数
    进入管理员/员工页面后,应通过return终止loginPage(),避免后续代码继续执行。


修复后的完整代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h> // 若使用getch()需包含此头文件

// 需确保该结构与写入文件时的定义完全一致
struct form {
    char username[30];
    char password[20];
    char roles[10];
    char status[10];
};

void adminPage();
void OUsersPage();
void relogin();

void loginPage(){
    char username[30], password[20];
    struct form login;
    FILE *admin;
    FILE *staff;
    int admin_found = 0, staff_found = 0;

    // 检查管理员文件是否成功打开
    admin = fopen("adminAcc.txt", "r");
    if(admin == NULL){
        printf("Failed to open admin account file!\n");
        getch();
        return;
    }

    // 检查员工文件是否成功打开
    staff = fopen("ordinaryUsers.txt", "r");
    if(staff == NULL){
        printf("Failed to open staff account file!\n");
        fclose(admin);
        getch();
        return;
    }

    // 登录输入处理
    printf("\nLogin Page");
    printf("\n================");
    printf("\nEnter Username: ");
    fgets(username, sizeof(username), stdin);
    username[strcspn(username, "\n")] = '\0'; // 移除输入末尾的换行符

    printf("Enter Password: ");
    fgets(password, sizeof(password), stdin);
    password[strcspn(password, "\n")] = '\0';

    // 遍历所有管理员账号
    while(fread(&login, sizeof(struct form), 1, admin)){
        if(strcmp(login.roles, "Admin") == 0){
            if(strcmp(username, login.username) == 0 && strcmp(password, login.password) == 0){
                system("cls");
                adminPage();
                admin_found = 1;
                break;
            }
        }
    }
    fclose(admin);

    if(admin_found){
        return; // 管理员匹配成功,终止当前函数
    }

    // 遍历所有员工账号
    while(fread(&login, sizeof(struct form), 1, staff)){
        if(strcmp(login.roles, "OU") == 0){
            if(strcmp(username, login.username) == 0 && strcmp(password, login.password) == 0){
                if(strcmp(login.status, "Disable") == 0){
                    printf("\nPlease wait for Admin to verify the account!");
                    getch();
                    system("cls");
                    relogin();
                }else{
                    system("cls");
                    OUsersPage();
                }
                staff_found = 1;
                break;
            }
        }
    }
    fclose(staff);

    // 所有账号均不匹配,触发重新登录
    if(!admin_found && !staff_found){
        relogin();
    }
}

额外注意事项

  • 确保写入adminAcc.txt和ordinaryUsers.txt时使用的struct form结构与读取时完全一致,否则fread会读取到错误数据。
  • 避免直接调用main()进行页面跳转,建议通过relogin()或重新调用loginPage()实现,防止栈溢出。
  • 修复后的逻辑支持多管理员/多员工账号,会遍历所有条目直到找到匹配项。

内容的提问来源于stack exchange,提问作者wanmoranIwhaledye

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 13:01:22