繁体   English   中英

传递给 fgets 的正确长度

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM