适当的长度传递给 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=]';
如果我有以下缓冲区:
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 byn
from the stream pointed to by stream into the array pointed to bys
. 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=]';