user-0 提问: 关于printf缓冲区的奇怪问题

回复:
user: user-1
content: 引用 5 楼 小菜瓜呱呱呱 的回复:引用 2 楼 wen_eric 的回复:帮顶版主，不好意思，我明白加fflush刷新缓冲区，但还是不明白为什么关闭stdout前加了printf就不用fflush了  首先：printf的缓冲有多重情况，标准输出是行缓冲，重定向到文件是全缓冲，而系统调用是不带缓冲的。所以在重定向后它是全缓冲，所以printf("Nice to meet you!\n");中"\n"不能刷缓冲，所以此时如果不调用fflush，nice to meet you 就不会被写入到文件。  其次如果在重定向之前调用了 printf("-------------1----------------\n");//加了这个printf即使不flush(stdout);也会正常写入文件，这是为什么 这句话，那么 printf 在重定向之后还是行缓冲，并没有变为全缓冲。在行缓冲中"\n"具有刷缓冲的功能。所以printf("Nice to meet you!\n"); 可以写入文件中。

user: user-2
content: 我也好奇。。按理说应该被改成全缓冲了啊？

user: user-3
content: 引用 15 楼 qq_29532941 的回复：遇到跟楼主一样的问题，请问楼主解决了吗？请教一下，为什么在close(1)之前加了printf后之后的printf可以正常输出呢？谢谢不是关闭stdout，是重定位到了txt文档，在重定位前加printf，然后之后的printf都可以正常输出到该文档，否则不行

user: user-3
content: 遇到跟楼主一样的问题，请问楼主解决了吗？请教一下，为什么在close(1)之前加了printf后之后的printf可以正常输出呢？谢谢

user: user-4
content: 行缓冲方式被改变，缓冲区满，刷新。

user: user-5
content: //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];

user: user-6
content: stdout默认是行缓冲的，也就是遇到\n刷新缓冲。你把它关了，重新打开的话，肯定缓冲模式就重置了。 http://man7.org/linux/man-pages/man3/setbuf.3.html setvbuf可以用设置为行缓冲或者无缓冲。  的确close、open属于无缓冲的API，所以close文件是不会同步缓冲的。 你应该用freopen("redir.txt", "w", stdout)这样用支持缓冲的方式重新打开文件stdout， 这样当你fclose时就会正确同步文件了。

user: user-7
content: 感觉楼主这里混淆了两套概念。linux C语言文件读写有两套API，一套是open，close，read这一类API，这些函数是系统调用，open返回的fd是一个整型数。还有一套API是C标准库中的fopen，fclose，fread等等，这是一类带缓冲的文件操作API，其中fopen返回的是一个FILE类型的指针。楼主的代码里貌似混用了这两套API，如果统一使用C标准库中以f开头的那些文件读写函数，是否还会出现这些问题？

user: user-8
content: 引用 9 楼 u014735054 的回复:[quote=引用 8 楼 paschen 的回复:] [quote=引用 6 楼 u014735054 的回复:] [quote=引用 3 楼 paschen 的回复:] http://en.cppreference.com/w/c/io/fflush 版主，不好意思，我明白加fflush刷新缓冲区，但还是不明白为什么关闭stdout前加了printf就不用fflush了[/quote]  prinf函数时可能会刷新缓冲区[/quote]为什么两个printf时第二个就刷新缓冲区，而一个printf的时候就没有刷新[/quote]  第一个的时候你不是还没打开文件

user: user-0
content: 引用 8 楼 paschen 的回复:[quote=引用 6 楼 u014735054 的回复:] [quote=引用 3 楼 paschen 的回复:] http://en.cppreference.com/w/c/io/fflush 版主，不好意思，我明白加fflush刷新缓冲区，但还是不明白为什么关闭stdout前加了printf就不用fflush了[/quote]  prinf函数时可能会刷新缓冲区[/quote]为什么两个printf时第二个就刷新缓冲区，而一个printf的时候就没有刷新

user: user-8
content: 引用 6 楼 u014735054 的回复:[quote=引用 3 楼 paschen 的回复:] http://en.cppreference.com/w/c/io/fflush 版主，不好意思，我明白加fflush刷新缓冲区，但还是不明白为什么关闭stdout前加了printf就不用fflush了[/quote]  prinf函数时可能会刷新缓冲区

user: user-0
content: 引用 4 楼 zhao4zhong1 的回复:printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];感谢回复，不过不太明白和我的问题的联系在哪里，不好意思请指教

user: user-0
content: 引用 3 楼 paschen 的回复:http://en.cppreference.com/w/c/io/fflush 版主，不好意思，我明白加fflush刷新缓冲区，但还是不明白为什么关闭stdout前加了printf就不用fflush了

user: user-0
content: 引用 2 楼 wen_eric 的回复:帮顶版主，不好意思，我明白加fflush刷新缓冲区，但还是不明白为什么关闭stdout前加了printf就不用fflush了

user: user-9
content: printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];

user: user-8
content: http://en.cppreference.com/w/c/io/fflush

user: user-10
content: 帮顶

user: user-11
content: #include <stdio.h>  int main() {     FILE* file = freopen("out.txt", "w", stdout);     if (file) {         printf("Nice to meet you!\n");     } } .... 我貌似记得fflush(stdout);不是标准?