适当的长度传递给 fgets

Proper length passed to fgets

如果我有以下缓冲区:

char buffy[40]; // includes [=10=] at the end

fgets 函数应该 STLEN 40 还是 39?为什么?

char buffy[40];
while (fgets(buffy, 40, fp) != EOF)
    // ...

fgets docs 中所述:

Arguments:
...
n - This is the maximum number of characters to be read (including the final null-character). Usually, the length of the array passed as str is used.

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

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 The fgets function:

Synopsis

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

Description

The fgets function reads at most one less than the number of characters specified by n from the stream pointed to by stream into the array pointed to by s. No additional characters are read after a new-line character (which is retained) or after end-of-file. A null character is written immediately after the last character read into the array.

所以

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

是正确的,但是

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

会更好

如果你会写例如

fgets(buffy, 39, fp)

那么函数 fgets 将不知道数组实际上包含 40 个字符。:)

所以数组的40-th元素将不会被使用并且是多余的。

当你用 40 个字符声明数组时

char buffy[40]; 

然后在 fgets 的调用中使用它们,例如

fgets(buffy, sizeof( buffy ), fp)

该函数将从字符串中读取不超过 39 个字符,并在数组中附加零字符 '[=19=]'

如果你需要从输入的字符串中删除换行符'\n'那么你可以这样写

buffy[ strcspn( buffy, "\n" ) ] = '[=13=]';