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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 22:36:09