#include <stdio.h>
#include <limits.h>
#include <windows.h>
void p(int n) {
if (n == 0) return;
p(n/10);
if (n%10 < 5) {printf("%d",n%10); Sleep(1000);}
}
int main()
{
printf("%d\n",INT_MAX-1);
p(INT_MAX - 1);
return 0;
}
它应该一次打印所有内容,因为流是缓冲的,但它会分别打印数字。我在windows下使用gcc。
答案 0 :(得分:4)
在C中,流有三种可能的缓冲状态:
_IONBF
- 无缓冲;字符应该尽快出现_IOLBF
- 行缓冲;字符应出现在换行符后_IOFBF
- 完全缓冲;在流刷新之前不应出现字符关于stdout
的初始状态,C11 7.21.3 / 7必须说:
最初打开时,标准错误流未完全缓冲;当且仅当可以确定流不参考交互设备时,标准输入和标准输出流是完全缓冲的。
由于流 是您的案例中的交互式设备,因此不得完全缓冲。因此,stdout
可以是行缓冲的也可以是非缓冲的。我没有看到任何其他文字进一步缩小这一点。
显然在您的系统上,它以无缓冲模式启动。
您可以使用以下方式设置线路缓冲:
setvbuf(stdout, NULL, _IOLBF, 1024);
(我不确定你应该为最后一个参数放置什么,但我认为这意味着它应该为该行使用1024字节的缓冲区;如果达到该限制则刷新)
然而,当我在MinGW-w64 4.9.2上尝试此操作时,行缓冲似乎与完全缓冲的行为相同。
我推测原因是因为此实现尽可能地将功能重定向到MSVC运行时库,并且MSVC运行时可能不支持行缓冲。这可以解释为什么gcc决定默认为无缓冲,因为这对于交互式程序而言比完全缓冲更好。
答案 1 :(得分:0)
在linux下的gcc上,这段代码:
#include <stdio.h>
#include <limits.h>
void p(int n){
if (n == 0) return;
p(n/10);
printf("%d",n);
}
int main()
{
printf("%d\n",INT_MAX-1);
p(INT_MAX - 1);
printf("\n");
return 0;
}
给出这个输出:
2147483646
2212142147214742147482147483214748362147483642147483646
或者为了清晰起见:
2 21 214 2147 21474 214748 2147483 21474836 214748364 2147483646
为了清晰起见,我已经取消了你的n%10的东西(因为我真的不明白为什么会这样)。
显然,我的系统没有刷新,我猜它必须是Windows本身正在做的事情。你的代码很好。
答案 2 :(得分:0)
在Linux上使用以下测试程序: #include
int main(int ac, char **av)
{
fprintf(stderr, "Pre\n");
printf("Hello world");
fprintf(stderr, "Post\n");
return 0;
}
运行时产生以下输出:
Pre<newline>
Post<newline>
Hello world<no newline>
鉴于[line buffered] stdout在[unbuffered] stderr之后出现,暗示缓冲区是用atexit处理程序刷新的,或者当程序终止并且libc被解除引用时。运行strace和ltrace表示第一个情况没有发生,因此输出可能在退出时刷新。
我怀疑在这个级别上,Windows和Linux的行为是一致的。如果它指向的是一个非stdout的文件,那么如果你忘了关闭文件,stdio子系统允许损坏文件(丢失的数据)将是非常糟糕的形式。