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

C语言fgets()函数使用异常:输入处理与输出错乱问题问询

问题排查与修正

核心问题:缓冲区溢出导致未定义行为

你代码里最致命的错误是缓冲区大小不匹配:

  • 定义char temporary[5]只有5字节空间,但调用fgets(temporary, 6, stdin)时,fgets最多会写入6字节(5个有效字符 + 1个终止符\0),直接造成数组越界,破坏栈上的内存数据(比如循环变量i),这就是输出错乱、换行异常的根源。

次要逻辑错误

  1. 无效的长度判断:strlen(temporary) > 5的判断完全没有意义——因为temporary只有5字节,正常情况下strlen最大为4(必须留1字节给\0),但溢出后strlen会读取越界的未知内存,结果不可靠。
  2. 未处理超长输入的残留数据:当输入的行长度超过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;
}

修正说明

  1. 缓冲区大小修正:temporary[6]刚好能容纳fgets写入的5个有效字符 + 1个\0,彻底解决越界问题。
  2. 超长输入处理:当输入字符数≥5时,fgets不会读取换行符,此时通过getchar()循环清空输入缓冲区的剩余内容,避免影响下一次读取。
  3. 需求匹配:
    • 输入4字符(如Barn)+ 换行:fgets会完整读取Barn\n,保留换行符,输出时自然换行后显示done。
    • 输入5字符(如Dhaka)+ 换行:fgets读取前5个字符Dhaka,清空缓冲区的换行符,输出时直接显示Dhaka done。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 18:43:32