Linux和Windows上的printf

这里是一些C代码:

int i; printf("This text is printed\nThis text is not until the for loop end."); for (i = 5; i > 0; i--) { printf("%d", i); sleep(1); } 

为什么'\n'之后的文本的其余部分在for循环开始之前不打印? 甚至在for循环中的printf只在循环结束后才被打印出来。 如果我在文本的末尾加上'\n' ,它会打印出来,但是我不想换行。

这只发生在Linux上,而不是在Windows上(只是改变睡眠(1)睡眠(1000)和添加windows.h)。

这是由输出缓冲引起的。 当您调用printf时,输出不会立即打印。 它被写入一个缓冲区,以备将来输出。 通常\n字符会导致缓冲区被自动刷新。 您也可以手动刷新标准输出缓冲区:

 printf("This text is printed\nThis text is not until the for loop end."); fflush(stdout); 

查找setvbuf()_IONBF_IOLBF_IOFBF 。 默认情况下,当输出到终端时,输出是行缓冲的( _IOLBF )。 这意味着输出仅在包含换行符时出现。 _IONBF是非缓冲的,有时为标准错误保留(尽管也可以行缓冲)。 _IOFBF是完全缓冲的; 直到内部缓冲区已满,或者显式地fflush()输出(或者,有时,如果从标准输入读取fflush() ,输出才会出现。 如果写入管道或文件,输出通常会被完全缓冲。

一般来说,如果你想及时看到它们,你应该期望用一个换行符来结束输出 – 尽管如此,基于Windows的例子还是相反的。 (这是Stack Overflow的一个常见模式,可以合理可靠地识别Windows程序编写的时间。)

stdout的缓冲区不是由C标准规定的。 但POSIX意味着(不要求)通常stdout在连接到终端时被行缓冲,否则被完全缓冲。

Linux遵循这个POSIX约定,但Windows不遵守。 您可以使用setvbuf更改默认行为,或者使用fflush刷新输出,这由C标准保证。