C语言中gets函数的替代方案及姓名匹配代码优化咨询
C语言代码优化方案
替换已弃用的gets函数
gets() 因为不检查输入缓冲区长度,存在严重的堆溢出风险,早在C11标准就被正式移除,推荐使用fgets()替代:
fgets()需要指定缓冲区最大长度,会自动截断超出长度的输入,避免溢出- 注意
fgets()会将输入末尾的换行符\n一起存入缓冲区,需要手动去除,否则后续字符串匹配会出错
原有逻辑问题优化
原有代码用strstr()直接匹配存在严重逻辑漏洞:只要输入的内容是姓名字符串的子串就会判定匹配成功,比如输入am会匹配到Sam,输入oh会匹配到John,不符合需求。
推荐优化方案:改用字符串指针数组存储所有姓名,遍历数组逐个精准匹配,逻辑更清晰易维护。
优化后完整代码
#include <stdio.h> #include <string.h> int main() { char who[110]; // 改用指针数组存储姓名,匹配逻辑更精准 const char *names[] = {"Sam", "John", "Tom", "Sophia", "Jane", "Mary"}; int name_count = sizeof(names) / sizeof(names[0]); int is_known = 0; printf("Enter a name: "); // 替换gets为fgets,指定缓冲区长度避免溢出 fgets(who, sizeof(who), stdin); // 去除fgets读入的末尾换行符 size_t len = strlen(who); if (len > 0 && who[len - 1] == '\n') { who[len - 1] = '\0'; } printf("\n%s\n", who); // 遍历姓名数组精准匹配 for (int i = 0; i < name_count; i++) { if (strcmp(who, names[i]) == 0) { is_known = 1; break; } } if (is_known) { printf("We know '%s'\n", who); printf("Hello %s", who); } else { printf("We don't know '%s'\n", who); printf("%s is a STRANGER!!", who); } return 0; }
核心优化点说明
- 输入安全:用
fgets()替代gets(),从根源避免缓冲区溢出漏洞,同时处理了输入末尾的换行符 - 匹配逻辑准确:改用指针数组存储姓名+
strcmp()逐一遍历匹配,完全避免子串误匹配的问题 - 可维护性提升:后续需要新增/删除姓名时,直接修改
names数组即可,无需调整字符串拼接逻辑
内容的提问来源于stack exchange,提问作者VII
相关产品推荐
相关产品推荐

