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

C语言使用fgets读取字符串的疑问:为何传入值需比数组大1?

fgets读取长度问题解析

先看你写的代码:

char array[4];
fgets(array , 5, stdin);

关于fgets参数的核心逻辑

你对fgets的核心认知是对的,但有个关键细节没理清:
fgets的第二个参数size指定的是目标缓冲区的总字节容量,它的规则是:最多读取size-1个有效字符,然后自动在末尾追加字符串终止符'\0',确保最终写入的总字节数不超过size。这就是为什么你会觉得它实际读的字符数比传入数值少1——因为C语言中字符串必须以'\0'结尾才能被正确识别,所以必须留一个字节的位置给这个终止符。

你的代码存在缓冲区溢出风险

你当前的代码有问题:数组array只有4个字节的空间,但你给fgets传了size=5,这会让fgets最多尝试写入5个字节(4个有效字符+1个'\0'),超出了数组的容量,属于缓冲区溢出,会破坏数组以外的内存,引发未定义行为(程序崩溃、数据错乱都有可能)。

正确的写法

如果你的需求是最多读取4个有效字符,正确的做法是:

char array[5]; // 留足5个字节:4个字符 + 1个'\0'
fgets(array, 5, stdin);

如果数组必须限定为4个字节,那fgets的第二个参数要传4,这样最多读取3个有效字符,加上终止符刚好占满4个字节:

char array[4];
fgets(array, 4, stdin);

另外补充:你说scanf会自动改变数组尺寸是错误的,scanf不会修改数组大小,只是超出数组长度写入时会直接溢出,同样引发未定义行为——这也是你选择fgets的正确原因:fgets可以通过参数控制写入的最大字节数,避免溢出,但前提是参数要和缓冲区大小匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 20:01:14