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

fgets()无法读取全部输入,求排查问题原因及解决方法

问题分析与解决

核心问题原因

  1. scanf遗留的输入缓冲区垃圾
    用scanf("%d", &size)读取整数后,你输入的回车(\n)会留在标准输入缓冲区里。后续调用fgets时,会先读取这个换行符,相当于读了个空行,这是第一个坑。

  2. fgets循环覆盖数据
    你的while(fgets(...))循环每次都会把新读取的内容覆盖到temp数组里,最后temp只保留最后一次读取的内容,之前的输入全被丢掉了——你输入pizza后按了回车,然后按^Z,最后一次fgets读取的是za(结合size=5的情况),所以最后输出的是这部分内容。

  3. fgets参数用错
    fgets的第二个参数是最大读取字符数(包含末尾的\0终止符),你传入size的话,最多只能读size-1个字符。而你定义的temp是size+1,应该传size+1才能利用全部空间。

  4. 输出逻辑混乱
    你直接把字符和索引连在一起输出,没有任何分隔,导致结果看起来乱糟糟的。


修复后的代码示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    int size = 0;
    do
    {
        printf("Put in size of the list (Range[1;2^16-1]): ");
        scanf("%d", &size);
        // 清空scanf遗留的换行符及缓冲区剩余内容
        while(getchar() != '\n');
        if (size <= 0)
            printf("Put in a correct length!\n");
    } while (size <= 0);

    char temp[size+1];
    // 只读取一行输入(如果要读取多行需要累积到其他缓冲区)
    if (fgets(temp, size+1, stdin) != NULL)
    {
        // 去掉fgets读取的末尾换行符(如果存在)
        temp[strcspn(temp, "\n")] = '\0';
    }

    // 修正输出格式,每个字符和索引分开显示
    for (int i = 0; i < strlen(temp); i++)
    {
        printf("字符: %c, 索引: %d\n", temp[i], i);
    }
    return 0;
}

关键改动说明

  • 清空输入缓冲区:在scanf后加while(getchar() != '\n');,把用户输入整数后剩下的回车和其他可能的垃圾字符全部清空,确保fgets读取的是用户真正输入的内容。
  • 去掉无意义的fgets循环:如果你的需求是读取一行输入,直接调用一次fgets即可;如果要读取多行,需要把每次fgets的内容追加到一个更大的缓冲区里(比如用malloc动态分配)。
  • 修正fgets的长度参数:传入size+1,让fgets最多读取size个有效字符(加上终止符刚好占满temp数组)。
  • 处理fgets的换行符:用strcspn找到换行符的位置并替换成\0,避免输出时带多余的换行。
  • 优化输出格式:把字符和索引用清晰的格式输出,方便查看结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 01:36:21