C语言开发Sign-Up and Log-In系统 如何比对输入与credentials.txt的账号密码
C语言登录验证实现方案与优化建议
用户名密码比对逻辑实现
你当前的代码已经将整个账号文件读取到了buffer内存中,结合注册时固定的存储格式,可通过字符串匹配完成校验,只需在现有登录代码的密码输入逻辑结束后,添加如下代码即可:
// 构造待匹配的用户名字符串 char target_user[30]; sprintf(target_user, "Username: %s\n", username); char *user_match = strstr(buffer, target_user); int login_status = 0; if (user_match != NULL) { // 找到对应用户名后,定位紧随其后的密码行 char *pass_match = strstr(user_match, "Password: "); if (pass_match != NULL) { // 跳过前缀,提取存储的密码内容 pass_match += strlen("Password: "); char stored_pwd[19] = {0}; for (int i = 0; pass_match[i] != '\n' && i < 18; i++) { stored_pwd[i] = pass_match[i]; } // 比对密码 if (strcmp(stored_pwd, password) == 0) { login_status = 1; } } } // 输出登录结果 if (login_status) { printf("登录成功\n"); } else { printf("用户名或密码错误\n"); } // 释放内存、关闭文件 free(buffer); fclose(credentials);
核心优化建议
- 替换危险函数
gets():该函数已被C11标准正式移除,无法限制输入长度,极易触发缓冲区溢出漏洞。可替换为fgets(username, sizeof(username), stdin),使用时额外处理掉字符串末尾的换行符即可。 - 修复长度校验逻辑:你当前定义的用户名/密码数组长度为19,最多可存储18个有效字符加末尾的
\0,现有判断len_u > sizeof(username)存在逻辑漏洞,应改为len_u >= sizeof(username)或直接判断长度是否超过18。 - 避免明文存储密码:练习场景也建议做简单的加密处理,比如将密码的每个字符ASCII码偏移固定值后再存入文件,读取时反向还原即可,避免账号文件泄露后密码直接暴露。
- 替换goto跳转逻辑:可使用do-while循环实现输入重试逻辑,代码可读性和可维护性更高。
- 增加注册用户名去重校验:当前注册逻辑允许同一个用户名重复注册,登录时只会匹配到第一个对应账号,建议注册时先遍历文件判断用户名是否已存在。
- 优化文件读取方式:无需一次性读取整个文件内容,使用
fgets()逐行读取解析更省内存,也更适配行存储的文本格式。 - 增加文件操作异常判断:补充
fprintf、fclose等函数的返回值校验,避免写入失败、文件操作异常时无任何提示。
内容的提问来源于stack exchange,提问作者Dev Shah
相关产品推荐
相关产品推荐

