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
相关产品推荐
相关产品推荐

