2011-11-23 77 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)退出處理程序 - 這樣的在程序要求操作系統拆除其內存並通知其父母已經死亡之前,輸出會被刷新。