1、输出缓冲区的行为
标准输出(stdout)通常是行缓冲的,也就是当遇到换行符('\n'
)时,缓冲区的数据会自动刷新并输出到屏幕。当缓冲区填满或程序正常结束时,也会自动刷新。如果没有触发这些条件,printf()
的输出会暂时保留在缓冲区中,而不会立即显示。
#include <stdio.h> int main() { // 设置 stdout 为无缓冲 setbuf(stdout, NULL); printf("这将会立即打印。\n"); // 设置 stdout 为行缓冲 char buffer[BUFSIZ]; setvbuf(stdout, buffer, _IOLBF, BUFSIZ); printf("这将在换行后打印。\n"); // 强制刷新缓冲区 fflush(stdout); printf("这将在 fflush 后立即打印。\n"); return 0; }
2、printf() 需要换行符才能刷新的原因
printf()
会将输出数据放入一个缓冲区。该缓冲区的默认刷新策略是,行缓冲在当遇到换行符('\n'
)时刷新,全缓冲在当缓冲区满了时刷新,无缓冲在对于 stderr,通常是无缓冲的,即每次输出都会立即显示。在大多数系统中,标准输出(stdout)是行缓冲的,所以一般会发现,没有换行符,输出会滞留在缓冲区中。有换行符会立即刷新并显示。
#include <stdio.h> #include <unistd.h> // for sleep() int main() { printf("This is the first line"); sleep(3); // simulate some delay printf("This is the second line\n"); return 0; }
3、解决方法
标准输出(stdout) 是行缓冲的,因此输出会在遇到换行符或缓冲区满时刷新。没有换行符时,你可以使用 fflush(stdout) 或禁用缓冲区来确保输出立即显示。stderr 是无缓冲的,适合需要立即输出的场景。
1)添加换行符
#include <stdio.h> int main() { printf("Hello\n"); // 使用换行符强制刷新缓冲区 return 0; }
2)使用 fflush() 手动刷新缓冲区
#include <stdio.h> int main() { printf("Hello"); // 没有换行符 fflush(stdout); // 手动刷新缓冲区 return 0; }
3)禁用缓冲
如要 stdout 每次输出时都立即显示,可以禁用缓冲。setbuf(stdout, NULL)
禁用了标准输出的缓冲,使所有输出立即生效。
#include <stdio.h> int main() { setbuf(stdout, NULL); // 禁用缓冲区 printf("Hello"); // 输出会立即显示 return 0; }
4)使用 stderr
stderr(标准错误)是无缓冲的,所以它的输出不会被缓冲。可以使用它来立即显示内容。
#include <stdio.h> int main() { fprintf(stderr, "Hello"); // 无缓冲,立即显示 return 0; }