即使已经达到 EOF,fgets() 是否总是终止 char 缓冲区?看起来确实如此(在 ANSI K&R 书中介绍的实现中确实如此),但我想我应该要求确认一下。
我想这个问题也适用于其他类似的函数,例如 gets()。
编辑:我知道这是在“正常”情况下附加的,我的问题是针对 EOF 或错误条件。例如:
FILE *fp;
char b[128];
/* ... */
if (feof(fp)) {
/* is \0 appended after EACH of these calls? */
fgets(b, 128, fp);
fgets(b, 128, fp);
fgets(b, 128, fp);
}
fgets
总是向读取缓冲区添加“ ”,因此它最多从流中读取 size - 1
个字符(size
是第二个参数)。
永远不要使用
gets
,因为你永远不能保证它不会溢出你给它的任何缓冲区,所以虽然它在技术上总是终止读取字符串,但这实际上没有帮助。
切勿使用获取!!
7.19.7.2 fgets 函数 概要 1 #包括char *fgets(char * 限制 s, int n, 文件*限制流); 描述 2 fgets函数读取最多比字符数少1个 由n指定从stream指向的流到指向的数组 至 s.换行符后不会读取任何其他字符 (被保留)或在文件结束之后。写入空字符 紧接着读入数组的最后一个字符之后。 退货 3 如果成功,fgets 函数返回 s。如果遇到文件结尾 并且没有字符被读入数组,数组的内容 保持不变并返回空指针。如果发生读取错误 在操作过程中,数组内容是不确定的并且为空 指针被返回。
所以,是,当
fgets()
不返回NULL时,目标数组总是有一个空字符。
如果
fgets()
返回 NULL,则目标数组可能已更改并且可能没有空字符。从 fgets()
获取 NULL 后切勿依赖数组。
编辑添加示例
$ cat fgets_error.c #包括无效 print_buf(char *buf, size_t len) { 整数 k; printf("%02X", buf[0]); 对于 (k=1;k 看到了吗? buf 中没有 NUL :)
男人fgets:
fgets() 从流中最多读入一个小于 size 的字符并将它们存储到 s 指向的缓冲区中。读取在 EOF 或换行符后停止。如果读取新行,则将其存储到缓冲区中。 “ ”存储在缓冲区中最后一个字符之后。
如果您确实以二进制模式“rb”打开文件,并且如果您想使用 fgets 逐行读取文本,则可以使用以下代码来保护您的软件不会丢失文本,如果文本错误地包含 ' ' 字节。 但最后就像其他人提到的那样,如果流包含 ' ',通常你不应该使用
。fgets
size_t filepos=ftell(stream); fgets(buffer, buffersize, stream); len=strlen(buffer); /* now check for > len+1 since no problem if the last byte is 0 */ if(ftell(stream)-filepos > len+1) { if(!len) filepos++; if(!fseek(stream, filepos, SEEK_SET) && len) { fread(buffer, 1, len, stream); buffer[len]='\0'; } }
是的,确实如此。来自CPlusPlus.com
从流中读取字符并将它们作为 C 字符串存储到 str 中,直到读取 (num-1) 个字符或到达换行符或到达文件结尾,以先到者为准。
换行符使 fgets 停止读取,但它被视为有效字符,因此包含在复制到 str 的字符串中。
复制到 str 的字符后会自动附加终止空字符。
男人fgets:
fgets() 从流中最多读入一个小于 size 的字符并将它们存储到 s 指向的缓冲区中。读取在 EOF 或换行符后停止。如果读取新行,则将其存储到缓冲区中。 “ ”存储在缓冲区中最后一个字符之后。
如果您确实以二进制模式“rb”打开文件,并且如果您想使用 fgets 逐行读取文本,则可以使用以下代码来保护您的软件不会丢失文本,如果文本错误地包含 ' ' 字节。 但最后就像其他人提到的那样,如果流包含 ' ',通常你不应该使用
fgets
。
size_t filepos=ftell(stream);
fgets(buffer, buffersize, stream);
len=strlen(buffer);
/* now check for > len+1 since no problem if the
last byte is 0 */
if(ftell(stream)-filepos > len+1)
{
if(!len) filepos++;
if(!fseek(stream, filepos, SEEK_SET) && len)
{
fread(buffer, 1, len, stream);
buffer[len]='\0';
}
}
是的,确实如此。来自CPlusPlus.com
从流中读取字符并将它们作为 C 字符串存储到 str 中,直到读取 (num-1) 个字符或到达换行符或到达文件结尾,以先到者为准。
换行符使 fgets 停止读取,但它被视为有效字符,因此包含在复制到 str 的字符串中。
复制到 str 的字符后会自动附加终止空字符。