C语言fgets()函数使用异常:输入处理与输出错乱问题问询
问题排查与修正
核心问题:缓冲区溢出导致未定义行为
你代码里最致命的错误是缓冲区大小不匹配:
- 定义
char temporary[5]只有5字节空间,但调用fgets(temporary, 6, stdin)时,fgets最多会写入6字节(5个有效字符 + 1个终止符\0),直接造成数组越界,破坏栈上的内存数据(比如循环变量i),这就是输出错乱、换行异常的根源。
次要逻辑错误
- 无效的长度判断:
strlen(temporary) > 5的判断完全没有意义——因为temporary只有5字节,正常情况下strlen最大为4(必须留1字节给\0),但溢出后strlen会读取越界的未知内存,结果不可靠。 - 未处理超长输入的残留数据:当输入的行长度超过5字符时,fgets只读取前5个字符,剩余字符会留在输入缓冲区,被下一次循环的fgets直接读取,导致后续读取逻辑混乱。
修正后的代码
#include <stdio.h> #include <string.h> int main() { char strs[5][6]; char temporary[6] = ""; // 修正缓冲区大小为6,适配fgets的6字节写入需求 for(int i = 0; i < 5; i++) { // 读取最多5个字符(含换行符),同时处理读取失败情况 if(fgets(temporary, 6, stdin) == NULL) { strcpy(strs[i], ""); continue; } size_t len = strlen(temporary); // 判断是否读取到换行符:没读到说明输入超长,清空缓冲区残留数据 if(temporary[len - 1] != '\n') { int c; while((c = getchar()) != '\n' && c != EOF); } strcpy(strs[i], temporary); } printf("%s done\n", strs[0]); printf("%s done\n", strs[1]); printf("%s done\n", strs[2]); printf("%s done\n", strs[3]); printf("%s done\n", strs[4]); return 0; }
修正说明
- 缓冲区大小修正:
temporary[6]刚好能容纳fgets写入的5个有效字符 + 1个\0,彻底解决越界问题。 - 超长输入处理:当输入字符数≥5时,fgets不会读取换行符,此时通过
getchar()循环清空输入缓冲区的剩余内容,避免影响下一次读取。 - 需求匹配:
- 输入4字符(如
Barn)+ 换行:fgets会完整读取Barn\n,保留换行符,输出时自然换行后显示done。 - 输入5字符(如
Dhaka)+ 换行:fgets读取前5个字符Dhaka,清空缓冲区的换行符,输出时直接显示Dhaka done。
- 输入4字符(如
内容的提问来源于stack exchange,提问作者Kabir
相关产品推荐
相关产品推荐

