为何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
相关产品推荐
相关产品推荐

