[英]Proper length passed to fgets
如果我有以下缓冲区:
char buffy[40]; // includes \0 at the end
fgets
function 应该有STLEN
40 还是 39? 为什么?
char buffy[40];
while (fgets(buffy, 40, fp) != EOF)
// ...
fgets
读取的字符数最多比它的第二个参数的值少一个。 因此,在这种情况下,正确的值应该是 40。 它将最多读取 39 个字符,并且数组的最后一个元素将用于存储 '\0'。 这确保不会发生缓冲区溢出。 作为成语
fgets(buf, sizeof buf, fp)
可以在(且仅当)数组buf
的声明可见时使用。
请注意,将其称为fgets(buf, 39, fp)
并没有错,但这将导致它最多读取 38 个字符,并且 '\0' 将存储在buf[38]
中(如果 38 个字符已阅读)。 数组的最后一个元素 ( buf[39]
) 根本不会被使用。
根据 C11 7.21.7.2 的 fgets function :
概要
#include <stdio.h> char *fgets(char * restrict s, int n, FILE * restrict stream);
描述
fgets
function 从 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ 指向的 stream 中读取最多比n
指定的字符数少一个到s
指向的数组中。 在换行符(保留)之后或文件结尾之后不会读取其他字符。 在读入数组的最后一个字符之后立即写入 null 字符。
所以
char buffy[40];
while (fgets(buffy, 40, fp) != NULL)
是正确的,但是
char buffy[40];
while (fgets(buffy, sizeof(buffy), fp) != NULL)
会更好。
如果你会写例如
fgets(buffy, 39, fp)
那么 function fgets
将对此一无所知,实际上该数组包含40
字符。:)
所以数组40-th
元素将不会被使用,将是多余的。
当您声明包含40
字符的数组时
char buffy[40];
然后在调用fgets
时使用所有这些,例如
fgets(buffy, sizeof( buffy ), fp)
function 将从字符串中读取不超过 39 个字符,并在数组后面附加零字符'\0'
。
如果您需要从输入的字符串中删除换行符'\n'
,那么您可以编写例如
buffy[ strcspn( buffy, "\n" ) ] = '\0';
如fgets
文档中所述:
Arguments:
...
n - 这是要读取的最大字符数(包括最后的空字符)。 通常,使用作为 str 传递的数组的长度。
所以,如果你的数组长度为 40,你应该使用 40。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.