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

基于C语言实现CSV文件用户身份认证的问题求助

C语言实现CSV用户身份认证的修正方案

问题背景

需要基于users.csv实现用户身份认证,CSV列固定格式为[id,user,pass,isAdmin],已定义如下User结构体:

struct User {
    int id;
    char user[20];
    char password[20];
    bool isAdmin;
};

现有getUser函数存在两个核心问题:

  • 使用strtok解析CSV时无法正确匹配用户名和密码
  • 验证通过后不知道如何初始化currentUser结构体

修正后的完整代码

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>

#define DELIMITER ","
#define MAX_USER_ROW_LENGTH 100

struct User {
    int id;
    char user[20];
    char password[20];
    bool isAdmin;
};

// 返回值:验证成功返回1,失败返回0
int getUser(struct User *currentUser, FILE *users) {
    char inputUser[20];
    char inputPass[20];
    
    printf("Enter username: ");
    scanf("%s", inputUser);
    printf("Enter password: ");
    scanf("%s", inputPass);

    char line[MAX_USER_ROW_LENGTH];
    // 重置文件指针到开头,避免多次调用时指针停在文件末尾
    fseek(users, 0, SEEK_SET);
    
    while (fgets(line, sizeof(line), users)) {
        // 去掉fgets读取的换行符,避免干扰字符串匹配
        line[strcspn(line, "\n")] = '\0';
        
        // 按固定列顺序解析CSV行
        char *token = strtok(line, DELIMITER);
        if (token == NULL) continue; // 跳过空行或不完整行
        int userId = atoi(token);
        
        token = strtok(NULL, DELIMITER);
        if (token == NULL) continue;
        char *csvUser = token;
        
        token = strtok(NULL, DELIMITER);
        if (token == NULL) continue;
        char *csvPass = token;
        
        token = strtok(NULL, DELIMITER);
        if (token == NULL) continue;
        bool isAdmin = (strcmp(token, "1") == 0 || strcmp(token, "true") == 0) ? true : false;
        
        // 匹配输入的用户名和密码
        if (strcmp(inputUser, csvUser) == 0 && strcmp(inputPass, csvPass) == 0) {
            // 安全初始化currentUser结构体
            currentUser->id = userId;
            // 用strncpy避免缓冲区溢出,手动添加字符串结束符
            strncpy(currentUser->user, csvUser, sizeof(currentUser->user) - 1);
            currentUser->user[sizeof(currentUser->user) - 1] = '\0';
            strncpy(currentUser->password, csvPass, sizeof(currentUser->password) - 1);
            currentUser->password[sizeof(currentUser->password) - 1] = '\0';
            currentUser->isAdmin = isAdmin;
            
            printf("Authentication successful!\n");
            return 1; // 验证成功,立即返回
        }
    }
    
    // 遍历所有行未匹配到,验证失败
    printf("Invalid username or password.\n");
    return 0;
}

关键修正说明

  • 修复strtok解析逻辑:

    • 按照CSV固定列顺序依次解析id、user、pass、isAdmin,而非无差别循环取token
    • 解析前去除换行符,避免干扰字符串比较
    • 添加空行/不完整行的跳过逻辑,防止程序崩溃
  • 正确初始化结构体:

    • 字符串不能直接用=赋值,必须用strncpy(限制拷贝长度避免缓冲区溢出),最后手动添加\0确保字符串合法
    • 用atoi将CSV中的id字符串转换为整数类型
    • 根据CSV中isAdmin的值(支持"1"/"0"或"true"/"false")转换为bool类型
  • 优化验证逻辑:

    • 原代码第一行不匹配就直接返回,现在遍历所有行后才判定验证失败
    • 添加fseek重置文件指针,确保函数多次调用时能重新读取文件
    • 将函数返回值改为int,方便调用者直接判断验证结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:06:30