读取并对比文本文件行:登录程序从文本文件数据库取密码失败求助
解决登录程序中用户名对应密码获取的问题
看起来你卡在了从文本文件关联用户名和密码的环节,还遇到了数组元素全为NULL的问题——别担心,我们一步步排查解决。
首先先明确你提到的文本文件格式:你给出的内容是mohammed badpassword1 fahad badpassword2 saad Badpassword3 faisal badpassword4 jack badpasswod5,这里大概率有两种可能:要么是每行一个用户名+密码(空格分隔),要么是用户名和密码各占一行(比如mohammed一行,badpassword1下一行)。你说想“传入用户名后获取其对应的下一行密码”,那应该是第二种格式,不过我会两种情况都覆盖到。
为什么你的数组元素都是NULL?
通常出现这种问题的原因不外乎这几个:
- 文件打开失败(比如路径错误、文件不存在),但你没做错误检查,导致后续读取全失败;
- 使用了字符指针数组(
char* users[])但没给每个指针分配内存,直接读取字符串进去导致内存错误; - 读取文件时没处理换行符,导致存储的用户名/密码包含
\n,后续匹配时出错; - 读取逻辑和文件实际格式不匹配(比如以为是每行一个用户+密码,但实际是用户名密码各占一行)。
解决方案代码示例(C语言)
我们用结构体存储用户名和密码的配对,这样更清晰,也能避免数组NULL的问题:
情况1:用户名和密码各占一行
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_USERS 5 #define MAX_STR_LEN 50 // 定义用户结构体,存储用户名和密码 typedef struct { char username[MAX_STR_LEN]; char password[MAX_STR_LEN]; } User; // 从文件加载用户数据 int load_users(User users[], const char* filename) { FILE* file = fopen(filename, "r"); if (!file) { perror("无法打开文件"); // 打印具体错误原因,比如文件不存在 return -1; } int user_count = 0; char temp_line[MAX_STR_LEN]; // 每次读取两行:先用户名,再密码 while (user_count < MAX_USERS && fgets(temp_line, MAX_STR_LEN, file) != NULL) { // 去掉换行符,避免影响后续字符串比较 strtok(temp_line, "\n"); strcpy(users[user_count].username, temp_line); // 读取对应的密码行 if (fgets(temp_line, MAX_STR_LEN, file) == NULL) { fprintf(stderr, "用户 %s 缺少对应的密码行\n", users[user_count].username); break; } strtok(temp_line, "\n"); strcpy(users[user_count].password, temp_line); user_count++; } fclose(file); return user_count; } // 根据用户名查找对应的密码 char* get_password(User users[], int total_users, const char* target_username) { for (int i = 0; i < total_users; i++) { if (strcmp(users[i].username, target_username) == 0) { return users[i].password; } } return NULL; // 找不到对应用户 } int main() { User users[MAX_USERS]; int total_users = load_users(users, "users.txt"); if (total_users <= 0) { printf("没有加载到任何用户数据\n"); return 1; } char input_username[MAX_STR_LEN]; printf("请输入用户名:"); fgets(input_username, MAX_STR_LEN, stdin); strtok(input_username, "\n"); // 去掉输入时的换行符 char* found_password = get_password(users, total_users, input_username); if (found_password) { printf("用户 %s 的密码是:%s\n", input_username, found_password); } else { printf("未找到该用户\n"); } return 0; }
情况2:每行是用户名+密码(空格分隔)
如果你的文本文件是每行一个用户和密码(比如mohammed badpassword1占一行),只需要修改load_users函数即可:
int load_users(User users[], const char* filename) { FILE* file = fopen(filename, "r"); if (!file) { perror("无法打开文件"); return -1; } int user_count = 0; char temp_line[MAX_STR_LEN]; while (user_count < MAX_USERS && fgets(temp_line, MAX_STR_LEN, file) != NULL) { // 用空格和换行符分割字符串,提取用户名 char* token = strtok(temp_line, " \n"); if (!token) continue; strcpy(users[user_count].username, token); // 提取密码 token = strtok(NULL, " \n"); if (!token) { fprintf(stderr, "用户 %s 缺少密码\n", users[user_count].username); continue; } strcpy(users[user_count].password, token); user_count++; } fclose(file); return user_count; }
调试建议
- 检查文件路径:确保
users.txt和程序在同一目录,或者使用绝对路径; - 打印读取内容:在加载用户时,打印每个读取到的用户名和密码,确认是否正确;
- 处理换行符:无论输入还是文件读取,记得用
strtok或者自定义trim函数去掉换行符,否则字符串比较会失败; - 内存检查:如果之前用的是
char*数组,一定要给每个指针分配足够的内存(比如users[i] = malloc(MAX_STR_LEN);),否则会出现NULL或者内存错误。
内容的提问来源于stack exchange,提问作者mohammad nassir
相关产品推荐
相关产品推荐

