Arrays 传递给FGET的适当长度

Arrays 传递给FGET的适当长度,arrays,c,char,c-strings,fgets,Arrays,C,Char,C Strings,Fgets,如果我有以下缓冲区: char buffy[40]; // includes \0 at the end fgets功能应该具有STLEN40还是39?为什么? char buffy[40]; while (fgets(buffy, 40, fp) != EOF) // ... 如合同所述: 参数: … n-这是要读取的最大字符数(包括最后的空字符)。通常,使用作为str传递的数组的长度 因此,如果数组长度为40,则应使用40。读取的字符数最多比第二个参数的值少一个。因此,在这种情况

如果我有以下缓冲区:

char buffy[40]; // includes \0 at the end
fgets
功能应该具有
STLEN
40还是39?为什么?

char buffy[40];
while (fgets(buffy, 40, fp) != EOF)
    // ...
如合同所述:

参数:

n-这是要读取的最大字符数(包括最后的空字符)。通常,使用作为str传递的数组的长度


因此,如果数组长度为40,则应使用40。

读取的字符数最多比第二个参数的值少一个。因此,在这种情况下,正确的值应该是40。它最多读取39个字符,数组的最后一个元素将用于存储“\0”。这确保不会发生缓冲区溢出。成语

fgets(buf, sizeof buf, fp)
当(且仅当)数组
buf
的声明可见时才可使用

请注意,将其称为
fgets(buf,39,fp)
没有什么错,但这将导致它最多读取38个字符,并且“\0”将存储在
buf[38]
中(如果已读取38个字符)。数组的最后一个元素(
buf[39]
)将完全不使用。

根据C11:

简介

    #include <stdio.h>
    char *fgets(char * restrict s, int n,
         FILE * restrict stream);
是正确的,但是

char buffy[40];
while (fgets(buffy, sizeof(buffy), fp) != NULL)

会更好。

如果你写一个例子

fgets(buffy, 39, fp)
fgets(buffy, sizeof( buffy ), fp)
buffy[ strcspn( buffy, "\n" ) ] = '\0'; 
然后函数
fgets
将不知道数组实际包含
40个字符。:)

因此,阵列的第40个
元素将不被使用,而是冗余的

正如您用
40个
字符声明数组一样

char buffy[40]; 
然后在调用
fgets
时使用它们,例如

fgets(buffy, 39, fp)
fgets(buffy, sizeof( buffy ), fp)
buffy[ strcspn( buffy, "\n" ) ] = '\0'; 
该函数将从字符串中读取不超过39个字符,并在数组中追加零字符
'\0'

如果需要从输入的字符串中删除新行字符
'\n'
,则可以编写示例

fgets(buffy, 39, fp)
fgets(buffy, sizeof( buffy ), fp)
buffy[ strcspn( buffy, "\n" ) ] = '\0'; 

可能会有帮助。
buffy
业力杀手
(fgets(buffy,40,fp)!=EOF
不是正确的测试。针对
NULL
进行测试。