即使已经达到EOF,fgets()总是使用\ 0终止char缓冲区吗?它看起来确实如此(它肯定在ANSI K& R书中提供的实现中),但我想我会要求确定。
我想这个问题适用于其他类似的函数,例如gets()。
编辑:我知道在“正常”情况下会附加\ 0,我的问题是针对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);
}
答案 0 :(得分:10)
fgets
总是向读缓冲区添加'\ 0',它会从流中读取最多size - 1
个字符(size
是第二个参数)因此。< / p>
永远不要使用gets
因为你永远不能保证它不会溢出你给它的任何缓冲区,所以虽然它在技术上总是终止读取字符串,但实际上并没有帮助。
答案 1 :(得分:8)
永远不要使用获取!!
7.19.7.2 The fgets function Synopsis 1 #include <stdio.h> char *fgets(char * restrict s, int n, FILE * restrict stream); Description 2 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. Returns 3 The fgets function returns s if successful. If end-of-file is encountered and no characters have been read into the array, the contents of the array remain unchanged and a null pointer is returned. If a read error occurs during the operation, the array contents are indeterminate and a null pointer is returned.
所以,是,当fgets()
没有返回NULL时,目标数组总是有一个空字符。
如果fgets()
返回NULL,则目标数组可能已更改,并且可能没有空字符。从fgets()
获取NULL后,永远不要依赖数组。
编辑示例已添加
$ cat fgets_error.c #include <stdio.h> void print_buf(char *buf, size_t len) { int k; printf("%02X", buf[0]); for (k=1; k<len; k++) printf(" %02X", buf[k]); } int main(void) { char buf[3] = {1, 1, 1}; char *r; printf("Enter CTRL+D: "); fflush(stdout); r = fgets(buf, sizeof buf, stdin); printf("\nfgets returned %p, buf has [", (void*)r); print_buf(buf, sizeof buf); printf("]\n"); return 0; } $ ./a.out Enter CTRL+D: fgets returned (nil), buf has [01 01 01] $
请参阅?在buf中没有NUL:)
答案 2 :(得分:4)
man fgets:
fgets()从流中读取最多一个小于大小的字符,并将它们存储到s指向的缓冲区中。读数在EOF或换行符后停止。如果读取新行,则将其存储到缓冲区中。 A'\ 0'存储在缓冲区中的最后一个字符之后。
答案 3 :(得分:2)
如果您确实以二进制模式&#34; rb&#34;打开文件,并且如果您想使用fgets逐行读取文本,则可以使用以下代码来保护软件丢失文本,如果通过文本中包含的错误是&#39; \ 0&#39;字节。
但最后与提及的其他人一样,如果流包含&#39; \ 0&#39;通常不应使用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';
}
}
答案 4 :(得分:0)
是的。来自CPlusPlus.com
从流中读取字符并将它们作为C字符串存储到str中,直到读取了(num-1)个字符或者到达了换行符或文件结尾,以先到者为准。
换行符使fgets停止读取,但它被认为是有效字符,因此它包含在复制到str的字符串中。
在读取字符后,空字符会自动附加在str中,以表示C字符串的结尾。