基于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 - 解析前去除换行符,避免干扰字符串比较
- 添加空行/不完整行的跳过逻辑,防止程序崩溃
- 按照CSV固定列顺序依次解析
正确初始化结构体:
- 字符串不能直接用
=赋值,必须用strncpy(限制拷贝长度避免缓冲区溢出),最后手动添加\0确保字符串合法 - 用
atoi将CSV中的id字符串转换为整数类型 - 根据CSV中
isAdmin的值(支持"1"/"0"或"true"/"false")转换为bool类型
- 字符串不能直接用
优化验证逻辑:
- 原代码第一行不匹配就直接返回,现在遍历所有行后才判定验证失败
- 添加
fseek重置文件指针,确保函数多次调用时能重新读取文件 - 将函数返回值改为
int,方便调用者直接判断验证结果
内容的提问来源于stack exchange,提问作者Ricardo Roel
相关产品推荐
相关产品推荐

