关于printf的刷新输出问题??

zhangjgbupt 2007-08-04 01:22:32
书上都说printf在输出字符串的时候,只有在字符串的最后有‘\n’,或者调用函数fflush(),或紧跟着printf后有scanf之类的,字符串才会显示,但是我发现即使没有这些条件,它一样正常显示呀,那个高手给解释一下。
...全文
1655 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
辰岡墨竹 2011-03-01
  • 打赏
  • 举报
回复
printf是有默认的行缓冲的,
你可以试试
printf("Waiting...");
//fflush(stdout);
while (1);
这个程序是个死循环,因为没有\n结束一行,printf内容是不会显示出来的,如果你去掉中间那行的注释,就会立刻显示的。
但是如果程序立刻结束的话,退出程序时行缓冲会被刷新,也会显示出来。

dongfang_123 2011-03-01
  • 打赏
  • 举报
回复

/*
============================================================================
Name : FileContentLockTest.c
Author : test
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>

static const char *test_file = "/home/lock_content.txt";
static void show_lock_info(struct flock *to_show);
#define SIZE_TO_TRY 5
int main(void) {
setbuf(stdout, NULL);
setbuf(stderr, NULL);
int file_desc;
int res;
struct flock region_to_test;
int start_byte;
file_desc = open(test_file, O_RDWR | O_CREAT, 0666);
if(!file_desc) {
fprintf(stderr, "Uable to open %s for read and write\n", test_file);
printf("%d", errno);
exit(EXIT_FAILURE);
}

for(start_byte = 0; start_byte < 99; start_byte += SIZE_TO_TRY) {
region_to_test.l_type = F_WRLCK;
region_to_test.l_whence = SEEK_SET;
region_to_test.l_start = start_byte;
region_to_test.l_len = SIZE_TO_TRY;
region_to_test.l_pid = -1;

printf("Testing F_WRCLK on regon for %d to %d\n",
start_byte, start_byte + SIZE_TO_TRY);

res = fcntl(file_desc, F_GETLK, ®ion_to_test);
if(res == -1) {
fprintf(stderr, "F_GETLK failed\n");
exit(EXIT_FAILURE);
}
if(region_to_test.l_pid != -1) {
printf("Lock would fail. F_GETLK returned:\n");
show_lock_info(®ion_to_test);
}
else {
printf("F_WRLCK - Lock would succeed\n");
}

/**共享锁**/
region_to_test.l_type = F_RDLCK;
region_to_test.l_whence = SEEK_SET;
region_to_test.l_start = start_byte;
region_to_test.l_len = SIZE_TO_TRY;
region_to_test.l_pid = -1;

printf("Testing F_WRCLK on regon for %d to %d\n",
start_byte, start_byte + SIZE_TO_TRY);

res = fcntl(file_desc, F_GETLK, ®ion_to_test);
if(res == -1) {
fprintf(stderr, "F_GETLK failed\n");
exit(EXIT_FAILURE);
}
if(region_to_test.l_pid != -1) {
printf("Lock would fail. F_GETLK returned:\n");
show_lock_info(®ion_to_test);
}
else {
printf("F_RDLCK - Lock would succeed\n");
}


}
close(file_desc);
exit(EXIT_SUCCESS);
}

void show_lock_info(struct flock *to_show) {
printf("\tl_type %d, ", to_show->l_type);
printf("l_whence %d, ", to_show->l_whence);
printf("l_start %ld, ", to_show->l_start);
printf("l_len %ld, ", to_show->l_start);

}

mymtom 2007-08-04
  • 打赏
  • 举报
回复
楼主可以在Unix/Linux下试试下面的程序:
#include <stdio.h>
#include <unistd.h>

int main(void)
{
(void)printf("Hello!");
fork();
return 0;
}

在fork之前加flush(stdout);
或者(void)printf("Hello!"); 给为(void)printf("Hello!\n")
然后比较一下输出就明白了.
iambic 2007-08-04
  • 打赏
  • 举报
回复
程序结束了会自动刷出缓冲区的。
qualcommbrew 2007-08-04
  • 打赏
  • 举报
回复
本人刚建一qq 39599204群(印证码 :C语言) 让有兴趣共同学习、共同提高、共同分享的同志加入。分享笔试、面试题让我们都可以拿高薪 哈哈 (欢迎上传面试,笔试题)本群建立48小时 还有22个名额 满了就没了 不会主动替人 请量解。哈哈
zhangjgbupt 2007-08-04
  • 打赏
  • 举报
回复
那为什么在在 gcc 和 vs.net 中的输出正常输出会正常呢???
comman_ndsc 2007-08-04
  • 打赏
  • 举报
回复
对,是这意思,但是即使不满足这三种情况照样可以显示在屏幕上呀,我觉得是不是编译器默认不缓冲?
---------------------------------------------------------------------------------------

可以把输出设置为不缓冲的。
星羽 2007-08-04
  • 打赏
  • 举报
回复

printf 无缓冲,cout 有缓冲;
缓冲刷新的时刻有:
1. 缓冲区满;
2. 输出 endl;
3. 显式调用 flush 函数;
4. 程序结束时。



C 中缓冲设置相关的函数:setbuf()



cout.setf(ios::stdio);
上述语句让 iostream 和 stdio 共用一个缓冲。



程序1:
////////////////////////////////////
#include "iostream.h"
#include "stdio.h"

int main()
{
cout << "ok1";
printf("%s", "ok");
cout << "ok2";

return 0;
}
////////////////////////////////////

程序1在 vc 6.0 里的输出结果为:
okok1ok2
其原因是:cout << "ok1"; 的时候没有刷新缓冲区,而 printf 输出后就刷新了。当 cout << "ok2"; 的时候,缓冲仍然没有被刷新。直到退出程序的时候,iostream 才刷新它的缓冲。所以 cout 的输出在 printf 后面。如果要顺序输出的话,在 cout 语句最后加上 << endl (cout << "ok1" << endl;),endl 会刷新缓冲的。

在 gcc 和 vs.net 中的输出正常,如下:
ok1okok2

程序2:
////////////////////////////////////
#include "iostream.h"
#include "stdio.h"

int main()
{
cout << "ok1";
printf("%s", "ok");
cout << "ok2";
for (int i = 1; i = 1; )
{
;
}

return 0;
}
////////////////////////////////////

程序2在 vc 6.0 里的输出结果为:
ok
其原因是:程序最后有个无限循环,所以cout没有机会被刷新(一般程序退出的时候 cout 会被刷新缓冲)。

在 gcc 和 vs.net 中的输出正常,如下:
ok1okok2



在多线程中用 printf 的话,其中的内容往往能在一个时间片内输出;而如果用 cout 的话,就不能够保证是否能在一个时间片内输出,即使加了 flush 或 endl 也一样。
zhangjgbupt 2007-08-04
  • 打赏
  • 举报
回复
对,是这意思,但是即使不满足这三种情况照样可以显示在屏幕上呀,我觉得是不是编译器默认不缓冲?
comman_ndsc 2007-08-04
  • 打赏
  • 举报
回复
printf将输出的数据传递给一个被称为缓冲区(buffer)的中介存储区域,缓冲区中的内容再向屏幕传输.
C规定缓冲区中的内容在如下三种情况向屏幕传输:缓冲区满,遇到换行符的时候或者需要输入的时候.
zhangjgbupt 2007-08-04
  • 打赏
  • 举报
回复
printf ()能是否显示是没有关系的。
-----------------
先将字符串输出到缓冲区,如果缓冲区满了就从缓冲区输出到标准输出设备上。
是不是编译器默认的不缓冲呀???
comman_ndsc 2007-08-04
  • 打赏
  • 举报
回复
是有输入输出缓冲区一说
fflush(stdout)可以用来刷新(清空)标准输出缓冲区。
scanf()是刷新标准输入缓冲区

但这和printf ()能是否显示是没有关系的。
cceczjxy 2007-08-04
  • 打赏
  • 举报
回复
有呀,输出都有缓冲区的,这个和缓冲区有关系,也就是说:按照书上说得,在遇到‘\n’,或者调用函数fflush(),或紧跟着printf后有scanf之类的,这三种情况就会刷新缓冲区,进而才能在显示出来

-------------------------------------------
这些情况是可用立即输出的,不过还有情况是你把输出设置成不缓冲,或则缓冲区设置的非常小.也会立即输出的
.在输出是,遇到缓冲区满了也会立即输出的.
zhangjgbupt 2007-08-04
  • 打赏
  • 举报
回复
有呀,输出都有缓冲区的,这个和缓冲区有关系,也就是说:按照书上说得,在遇到‘\n’,或者调用函数fflush(),或紧跟着printf后有scanf之类的,这三种情况就会刷新缓冲区,进而才能在显示出来
comman_ndsc 2007-08-04
  • 打赏
  • 举报
回复
printf的刷新输出???有
------------------------
没听过这种说法啊!


书上都说printf在输出字符串的时候,只有在字符串的最后有‘\n’...
------------------------------------------------------------------
如果单单说输出字符串的话,我想应该是判断到'\0'的时候,显示,
printf ()函数主要还是用在格式输出上,没有像楼主说的那么复杂啊。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧