C:fwrite()与(f)printf?
我正在阅读C:fwrite()与(f)printf?,c,printf,fwrite,C,Printf,Fwrite,我正在阅读getline函数的手册页面,看到了它的演示: #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { FILE *stream; char *line = NULL; size_t len =
getline
函数的手册页面,看到了它的演示:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
FILE *stream;
char *line = NULL;
size_t len = 0;
ssize_t nread;
...
while ((nread = getline(&line, &len, stream)) != -1) {
printf("Retrieved line of length %zu:\n", nread);
fwrite(line, nread, 1, stdout); /* ? */
}
free(line);
fclose(stream);
exit(EXIT_SUCCESS);
}
定义GNU源
#包括
#包括
int
main(int argc,char*argv[])
{
文件*流;
char*line=NULL;
尺寸长度=0;
ssize_t nread;
...
while((nread=getline(&line,&len,stream))!=-1){
printf(“检索到的行的长度为%zu:\n”,nread);
fwrite(行,nread,1,stdout);/**/
}
自由线;
fclose(流);
退出(退出成功);
}
我将fwrite()
语句替换为printf(“%s”,line)
,它生成了
相同的结果(使用cmp
和diff
进行比较)。我知道fwrite
和fprint
之间的区别,但在这种情况下,作者选择使用fwrite()
而不是fprintf
或printf
有什么具体原因吗
但是,在这种情况下,作者选择在fprintf或printf上使用fwrite()有什么具体原因吗
研究fwrite
和fprintf
的内部实现
您会发现,fprintf
比fwrite
更复杂、更脆弱,因此速度较慢。这也很难理解
另外,一些编译器(有时包括)能够(在简单的情况下)将对fprintf
的一些调用转换为类似于您的fwrite
的内容。您可以尝试将foo.c
源代码编译为gcc-Wall-O3-fverbose asm-S foo.c
,并查看生成的汇编代码foo.S
但是,在这种情况下,作者选择在fprintf或printf上使用fwrite()有什么具体原因吗
研究fwrite
和fprintf
的内部实现
您会发现,fprintf
比fwrite
更复杂、更脆弱,因此速度较慢。这也很难理解
另外,一些编译器(有时包括)能够(在简单的情况下)将对
fprintf
的一些调用转换为类似于您的fwrite
的内容。您可以尝试将您的foo.c
源代码编译为gcc-Wall-O3-fverbose asm-S foo.c
,并查看生成的汇编程序代码foo.Sfwrite(line,nread,1,stdout)
和printf(“%S”,line)
之间的差异包括:
printf(“%s”,第行)
最多写入第一个空字符
fwrite(行,nread,1,stdout)
写入输入长度
这在读取空字符时有所不同,因此使用fwrite()
可在该病理情况下提供正确的功能。在fwrite(line,nread,1,stdout)
和printf(“%s”,line)
之间的差异包括:
printf(“%s”,第行)
最多写入第一个空字符
fwrite(行,nread,1,stdout)
写入输入长度
这与读取空字符时不同,因此在这种情况下使用fwrite()
可以提供正确的功能。一个写入格式化数据,一个写入内存内容。使用任何一个都是完全根据情况而定的(就像标准库中的其他内容一样,在使用它之前要知道它的作用)。如果使用printf
,当输入数据包含任何空字节时会发生什么?顺便问一句,为什么要删除你的,这是一个相当好的重复路标,因为它是…一个写格式化数据的人,一个写内存内容。使用任何一个都是完全根据情况而定的(就像标准库中的所有其他内容一样,在使用它之前要知道它的功能)。如果使用printf
,当输入数据包含任何空字节时会发生什么情况?顺便问一句,为什么要删除,这是一个相当不错的复制路标…但是getline
不会读取NULL
字符…@BasileStarynkevitch我不同意。请提供说明getline()
读取空字符与其他字符不同的信息。@basilestrynkevitch事实上,我看到“在成功时,getline()和getdelim()返回读取的字符数,包括分隔符,但不包括终止的空字节('\0'))。此值可用于处理读取行中嵌入的空字节。“对不起,我错了,但是getline
不会读取null
字符…@BasileStarynkevitch我不同意。请提供说明getline()
读取空字符与其他字符不同的信息。@basilestrynkevitch事实上,我看到“在成功时,getline()和getdelim()返回读取的字符数,包括分隔符,但不包括终止的空字节('\0'))。此值可用于处理读取行中嵌入的空字节。“很抱歉,我错了。如果我遵循的正确,差异将归结为解释格式字符串的成本,以及用正确的值替换格式说明符的成本。在这种情况下,fwrite
的成本将更接近于在缓冲区之间复制一些数据的成本,以及可能的fflush
系统调用。最重要的不同是C源代码的可读性。在这种情况下,可读性不是一个区别。这两个版本都很简单,可以理解为一个例子。如果我正确地理解了,那么差异就归结为解释格式字符串的成本,以及用正确的值替换格式说明符的成本。在这种情况下,fwrite
的成本将更接近于在缓冲区之间复制一些数据的成本,以及可能的fflush
系统调用。最重要的不同是C源代码的可读性在这种情况下,可读性不是