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

如何在C语言运行时设置fgets()读取长度?求助排查问题

为什么用scanf输入长度后fgets会被跳过?

问题出在scanf("%d", &i)的输入处理逻辑上:当你输入数字并按下回车时,scanf只会读取输入中的数字部分,而回车产生的换行符\n会残留在标准输入缓冲区里。

当后续调用fgets(str, i, stdin)时,fgets会从缓冲区里读取字符,它一遇到这个残留的换行符就会停止读取(因为fgets以换行符作为行结束标志),直接返回空行,看起来就像被“跳过”了,实际上它已经完成了读取操作。

而硬编码版本能正常运行,是因为程序启动后输入缓冲区是空的,fgets会等待用户输入,不会被残留的换行符干扰。

解决方法

  • 方法一:手动清空缓冲区残留的换行符
    在scanf之后调用getchar(),读取并丢弃缓冲区里的换行符:

    #include <stdlib.h>
    #include <stdio.h>
    
    int main() {
       int i;
       char str[100];
    
       puts("Enter a number: ");
       scanf("%d", &i);
       getchar(); // 吃掉残留的换行符
       fgets(str, i, stdin);
       printf("String contents: %s", str);
       return 0;
    }
    

    注意:如果用户输入数字后还输入了其他非数字字符(比如123abc\n),getchar()只能处理一个字符,这种情况可以用循环清空整个缓冲区:

    while ((getchar()) != '\n');
    
  • 方法二:用fgets读取数字输入,再转换为整数
    这种方法可以彻底避免缓冲区残留问题,同时还能处理更复杂的输入情况:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    int main() {
       int i;
       char num_str[20];
       char str[100];
    
       puts("Enter a number: ");
       fgets(num_str, sizeof(num_str), stdin);
       // 去掉num_str里的换行符(如果存在)
       num_str[strcspn(num_str, "\n")] = '\0';
       i = atoi(num_str); // 或者用strtol做更安全的转换
       // 确保i不超过数组长度,避免缓冲区溢出
       if (i > 100) {
           i = 100;
       }
       fgets(str, i, stdin);
       printf("String contents: %s", str);
       return 0;
    }
    

    推荐使用strtol代替atoi,因为它能检测转换错误,比如输入非数字字符的情况。

额外提醒

无论用哪种方法,都要确保输入的i不超过数组str的长度(这里是100),否则会导致缓冲区溢出,引发未定义行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 15:54:13