2011-11-23 78 views
2

为什么printf的输出在出线时不显示?但在某些时候它没有印刷生产线16调试时GDB printf奇怪的输出

C文件:

#include<stdio.h> 

void nextfunc(){ 
    int ctr;  
    for(ctr = 0; ctr<3; ctr++){ 
     printf("print ctr = %d",ctr); 
    } 
    printf("last print"); 
} 
void main(){ 

    int x; 
    printf("input x: "); 
    scanf("%d",&x); 
    printf("\nprint 2"); 
    printf("\nprint 3"); 
    nextfunc(); 
} 

GDB:

(gdb) break main 
    Breakpoint 1 at 0x8048479: file file5.c, line 14. 
    (gdb) break nextfunc 
    Breakpoint 2 at 0x804843a: file file5.c, line 6. 
    (gdb) run 
    Starting program: /home/charmae/workspace/AVT/file5 

    Breakpoint 1, main() at file5.c:14 
    14  printf("input x: "); 
    (gdb) s 
    15  scanf("%d",&x); 
    (gdb) s 
    input x: 4 
    16  printf("\nprint 2"); 
    (gdb) s 

    17  printf("\nprint 3"); 
    (gdb) s 
    print 2 
    18  nextfunc(); 
    (gdb) s 

    Breakpoint 2, nextfunc() at file5.c:6 
    6  for(ctr = 0; ctr<3; ctr++){ 
    (gdb) s 
    7   printf("print ctr = %d",ctr); 
    (gdb) s 
    6  for(ctr = 0; ctr<3; ctr++){ 
    (gdb) s 
    7   printf("print ctr = %d",ctr); 
    (gdb) s 
    6  for(ctr = 0; ctr<3; ctr++){ 
    (gdb) s 
    7   printf("print ctr = %d",ctr); 
    (gdb) s 
    6  for(ctr = 0; ctr<3; ctr++){ 
    (gdb) s 
    9  printf("last print"); 
    (gdb) s 
    10 } 
    (gdb) s 
    main() at file5.c:19 
    19 } 
    (gdb) s 
    0x0014a113 in __libc_start_main() from /lib/i386-linux-gnu/libc.so.6 
    (gdb) s 
    Single stepping until exit from function __libc_start_main, 
    which has no line number information. 
    print 3print ctr = 0print ctr = 1print ctr = 2last print[Inferior 1 (process 2578) exited with code 012] 

回答

2

输出尽管stdout被缓冲。这意味着它被保存在一个临时缓冲区中,直到缓冲区满了,打印一个换行符或调用函数fflush(stdout)。程序结束时,也会自动刷新stdout

你输出打印在“错误的地方”在GDB的原因是因为这种缓冲。您应该在printf格式字符串的末尾添加换行符,或者明确地呼叫fflush

1

的技巧是,你没有把一个换行符:

printf("last print"); 

标准IO库将缓冲输出,直到它看到要打印的换行符。输出到终端通常是线路缓冲的;可能gdb运行该程序就好像它连接到一个终端,所以它会打印前面的行,其中包含\n字符。

输出实际上在输出你有:在退出前

... ctr = 2last print[In ... 

标准IO库刷新所有的输入流 - 通过atexit(3)退出处理程序 - 这样的在程序要求操作系统拆除其内存并通知其父母已经死亡之前,输出会被刷新。