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

为何gets()可正常运行而fgets()在回文检测代码中失效?

回文检测中fgets失效、gets正常的原因及修复方案

问题现象

编写的字符串回文检测程序,使用fgets()读取输入时,明明输入是回文字符串,strcmp()却返回1,判定不是回文;替换成不安全的gets()后程序正常工作。调试输出显示两个字符串看起来完全一致,但比较结果不相等。

核心原因

fgets()与gets()的行为差异:

  • gets()会自动丢弃输入末尾的换行符\n,只保留输入的文本内容。
  • fgets()会将用户输入时按下的换行符也读取到目标字符串中,最终字符串是输入内容\n\0的格式。

以输入tacocat为例:

  • fgets()读取后,word的内容是"tacocat\n"
  • 复制到drow后,strrev(word)会把word变成"\ntacocat"
  • 此时strcmp(drow, word)比较的是"tacocat\n"和"\ntacocat",两者ASCII码顺序不同,返回1,导致判定错误。

而gets()读取后word是"tacocat",反转后与原字符串完全一致,strcmp()返回0,程序正常。

修复方案

使用fgets()读取后,手动去除字符串末尾的换行符,避免其影响后续反转和比较。修改后的代码如下:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define LEN 20

int main()
{
    char word[LEN], drow[LEN];
    printf("Insert a word: ");
    fgets(word, LEN, stdin); // 数组长度为LEN,fgets会自动预留终止符位置,无需+1

    // 去除fgets读取的换行符
    size_t len = strlen(word);
    if (len > 0 && word[len - 1] == '\n') {
        word[len - 1] = '\0';
    }

    strcpy(drow, word);
    strrev(word);

    puts(word);
    puts(drow);

    printf("strcmp=%d\n", strcmp(drow, word));

    if(strcmp(drow,word) == 0){
        printf("The string is a palindrome\n");
    }
    else{
        printf("The string isn't a palindrome\n");
    }

    return 0;
}

注意事项

永远不要使用gets():它不检查输入长度,当输入内容超过缓冲区大小时会造成缓冲区溢出,引发程序崩溃或安全漏洞,该函数已在C11标准中被移除。

内容的提问来源于stack exchange,提问作者santi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:27:16