今天看到CU上C版的有朋友代码及输出结果是这样的
#include <stdio.h> 
  main() 
{ 
        printf("1."); 
          sleep(2); 
        printf("2."); 
        sleep(2); 
          printf("3."); 
        sleep(2); 
        printf("4."); 
          printf("OK\n"); 
} 
%gcc test.c 
  %./a.out 
1.2.3.4.OK
sleep没起到作用,而是这些1.2.3.4过了好一会一起输出了。
  我试了一下,果然是这样,gcc编译的
看楼下高人们的说法是因为行缓冲,系统会把一行的数据一起输出,而不是打印一点,就输出一点。呵呵
标准输出是带有行缓冲的,解决办法有好几种:
  我在每个后面加了换行,问题就没有了
[ktktkt@Jintao COMMON]$ cat 1.c
#include <stdio.h>
  int main()
{
        printf("1\n");
          sleep(2);
        printf("2\n");
        sleep(2);
          printf("3\n");
        sleep(2);
        printf("4\n");
          sleep(2);
        printf("5\n");
        sleep(2);
          return 0;
}
这样由于有了换行,就不再一起输出了:)
  [ktktkt@Jintao COMMON]$ ./1
1
2
3
  4
5
还有解决办法是,在没有\n换行时,在每行后面强制刷新
  [ktktkt@Jintao COMMON]$ cat 1.c
#include <stdio.h>
int main()
{
        printf("1 ");
          fflush(stdout);
        sleep(2);
        printf("2 ");
          fflush(stdout);
        sleep(2);
        printf("3 ");
          fflush(stdout);
        sleep(2);
        printf("4 ");
          fflush(stdout);
        sleep(2);
        printf("5 ");
          fflush(stdout);
        sleep(2);
        return 0;
}
结果是这样的:
  [ktktkt@Jintao COMMON]$ ./1
1 2 3 4 5 
的确是两秒两秒输出的,蛮爽~
  这个小tip蛮过瘾~
但是问题在于编译时指定-Wall仍然会有warning提示:
  sleep函数没有?
[ktktkt@Jintao COMMON]$ gcc 1.c -o 1 -Wall
1.c: In function `main':
  1.c:7: warning: implicit declaration of function `sleep'
man了一下
  #man 3 sleep
发现是unistd.h里边的,于是加上这一行,再编译,没有问题了:),代码变成下面这样:
#include <stdio.h>
#include <unistd.h>
int main()
{
        printf("1 ");
          fflush(stdout);
        sleep(2);
        printf("2 ");
          fflush(stdout);
        sleep(2);
        printf("3 ");
          fflush(stdout);
        sleep(2);
        printf("4 ");
          fflush(stdout);
        sleep(2);
        printf("5 ");
          fflush(stdout);
        sleep(2);
        return 0;
}
这样就编译成功了...
flw老大的解释:
解决的办法有以下几种: 
1,改用 printf( "1\n" ) 但是这种方法有时候是作者不愿意的。 
  2,改用 fprintf( stderr, "1" ) 因为 stderr 不是行缓冲的,所以可以这么做。我就经常采用这种方法,但是这种方法在输出重定向的时候,是要特别处理的,换句话说,它不符合和 shell 交互的某些规范。开发出来的程序不符合 shell 过滤器的习惯。 
3,改用 printf( "1\n" ) + fflush(stdout) 这是唯一的一种既不影响作者原意,又可以产生预期的效果的方法。说严格点,这是唯一正确的方法,因为这种方法不会影响到任何人、任何事。 
  4,直接用某种手段修改你的 stdout 的属性,使之变成非行缓冲的,比如调用 ioctl 等系统调用或者是用操作系统提供的命令……
 
 
没有评论:
发表评论