#include <stdio.h>
#define MAXLEN 256
int main() {
int n;
char buf[MAXLEN];
while((n = read(0,buf,sizeof(buf))) != 0){
printf("n: %d:",n);
write(1,buf,n);
}
return 1;
}
程序的输出(用户输入第一个read
和第一个write
并由终端回显):
read
read
write
write
n: 5:n: 6:
在标准输入处按Ctrl + D后,printf的输出出现,而不是随后的读取。为什么会这样?
答案 0 :(得分:20)
Printf已缓冲。
您可以使用fflush调用强制printf“刷新”其缓冲区:
#include <stdio.h>
#define MAXLEN 256
int main() {
int n;
char buf[MAXLEN];
while((n = read(0,buf,sizeof(buf))) != 0){
printf("n: %d:",n);
fflush(stdout); /* force it to go out */
write(1,buf,n);
}
return 1;
}
一般来说,printf()
被缓冲是一件好事。无缓冲输出,尤其是需要屏幕更新等的可见控制台,速度很慢。足够慢以至于可以直接减慢打印很多的应用程序(特别是在Windows平台上; Linux和unix通常受影响较小)。
但是,如果printf()
- fprintf(stderr,)
故意无缓冲,则stderr
被缓冲会让你感到困惑。因此,您可能会收到包含printf()
个邮件的邮件。如果您写入另一个与终端关联的FILE
句柄,并且可能没有缓冲,请确保首先明确fflush(stdout)
。
答案 1 :(得分:2)
fgets的联机帮助页告诉我:
不建议将调用混合到stdio中的输入函数 具有低级调用的库,用于读取文件描述符关联(2) 与输入流一起使用;结果将是不确定的 可能不是你想要的。
因此,最好的解决方案是不要在同一个描述符上使用write和printf。
答案 2 :(得分:1)
Printf正在使用stdio并且它是缓冲的。 通过发送更改为“n:%d:\ n”
将其推出答案 3 :(得分:1)
您可以使用std fflush()函数来刷新标准输出缓冲区,或者您可以在printf内的控制字符串末尾使用额外的\ n。像这样的东西
printf("\n :%d:\n",n);
最好使用write()&amp; read()函数用C代替printf()和scanf()。 printf和scanf遇到了一些问题,比如printf将字符串参数存储在stdout缓冲区中。因此需要手动冲洗,这通过fflush功能或通过\ n进行。在一个小的hello world打印程序中,你不会发现这样的问题,因为stdout缓冲区在程序执行结束时被刷新。更好的使用write()工作正常。 scanf也有读取空间的问题以及与stdin缓冲区相关的许多其他问题。
例如,在下面的代码中:
main() { char a; int i=0,c; for(;i<2;i++) { scanf("%d",&c); scanf("%c",&a);} }
上面的程序在按下回车时读到了进入标准输入的问题。我们可以解决这个问题,但不能刷新stdin缓冲区或使用\ n字符。总是更好地使用read()和write()函数。
希望有所帮助....
答案 4 :(得分:0)
使用fwrite(流版本)而不是写。
请注意,虽然与文件编号1相关联,但它不是一回事。