关于fgets()函数
函数原型:char *fgets(char *s, int size, FILE *stream);
功能描述:fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('\0') is stored after the last character in the buffer.
“fgets从流上读取最多(size-1)个字符并将其存储到s指向的buffer中,当遇到新的一行或文件结束标志时结束。如果读到一个新行(a newline),会把它存储到buffer中。最后会在最后一个字符的后面添加一个字符串结束标记——'\0'。”
以上描述中有个难以理解的地方——什么是一个newline?为什么把它也存入buffer中?
实际上,经过代码测试可知:newline其实指的是换行符'\n'
另外一个需要注意的地方是最后面添加的字符串结束标记'\0'
由于以上两个特性,buf可以直接用printf打印,并且自带换行符。
测试程序如下,该程序可以结合重定向实现文件的复制。注:fgets获取到的换行符并不会导致文件复制时中间多出空行,相反,这正符合文件复制时的需要
/* cp2.c - cp with gets and printf */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define DEBUG int main() { char buf[BUFSIZ]; while( fgets(buf, BUFSIZ, stdin) != NULL ) { #ifdef DEBUG if( buf[strlen(buf)] == '\0' ) puts( "fgets gets a line from stdin or file, appended with '0'" ); if( buf[strlen(buf) - 1] == '\n' ) puts( "fgets gets a line with '\\n'" ); #endif printf( "%s", buf ); } exit( 0 ); }
测试用例及结果如下:
lim@ubuntu:~/APUE/chap1$ ./cp2 < cp2.c fgets gets a line from stdin or file, appended with '0' fgets gets a line with '\n' /* cp2.c - cp with gets and printf */ fgets gets a line from stdin or file, appended with '0' fgets gets a line with '\n' #include <stdio.h>... fgets gets a line from stdin or file, appended with '0' fgets gets a line with '\n' printf( "%s", buf ); fgets gets a line from stdin or file, appended with '0' fgets gets a line with '\n' } fgets gets a line from stdin or file, appended with '0' fgets gets a line with '\n' exit( 0 ); fgets gets a line from stdin or file, appended with '0' fgets gets a line with '\n' } lim@ubuntu:~/APUE/chap1$
最后,还有一个问题:fgets在后面补'\0',但如果一行的长度大于size呢?
以下测试可知,当一行的长度大于size时,只会得到size-1个字符,而最后一个字符留给'\0'。
当一行长度小于size时:
当一行的长度大于等于size时:
通过以上实验,验证了函数功能描述中所说的"at most one less than size"