2014-10-18 68 views
3

我寫一個程序使用用於循環和印刷後打印整數值,程序應該等待1秒鐘,在此之後的那些整數是重寫與換句話說程序的目的是雙重的空格字符等待一秒鐘後擦除這些整數。在C環括號

此程序:

#include <stdio.h> 
#include <time.h> 

int main (void) { 
    int i; 

    for(i=1;i<=5;i++){ 
     printf("%d ",i); 
    } 

    for(;clock() < CLOCKS_PER_SEC;){} /*wait for one second*/ 

    printf("\r");  /*move to the beginning of the line*/ 
    for(i=1;i<=5;i++){ 
     printf(" "); /*overwriting the integers*/ 
    } 
    printf("\n"); 

    return 0; 
} 

的問題是在等待循環環路括號`爲(;時鐘()< CLOCKS_PER_SEC;){}」時,我 正確刪除那些括號中的程序工作。但是如果帶括號的for循環。該程序不起作用,我的意思是程序仍然運行,但它覆蓋整數,而不是先顯示那些整數。

請有人解釋發生了什麼?

回答

2

你沒有刷新自己的標準輸出,因此不會發生,直到「\ r」被寫入(即printf的寫入流),然後立即將其清除。

如果刪除{},那麼你的循環就等於

for(;clock() < CLOCKS_PER_SEC;) 
    printf("\r"); 

它寫了一堆\r,其中第一個刷新輸出,其餘這些都是多餘的。循環完成後,您可以清除該行,按照您的要求工作。

您應該在打印後的數字撥打fflush(stdout)。或者您可以移動printf(「\ r」),使其位於等待循環之前(不同之處在於遊標結束處)。

你的循環有問題,因爲不能保證clock()從0開始,並且它不會在很多系統上運行,並且你不應該像這樣旋轉......它會減慢系統上運行的其他程序。你可以使用sleep(1),雖然它不是很準確。

1

我懷疑莫名其妙輸出緩衝器被兩種情況之間不同的沖洗。你可以通過在有問題的循環之前使用fflush(stdout)手動清空緩衝區來檢查。

另外請注意,{}是不是在C強制性的,對於內環路單行語句。

+0

你能解釋一下我準確地說了'stdout'嗎? – harianja 2014-10-18 03:08:14

+0

@傑里米弗里斯納的回答更貼切和正確。標準輸出是「標準輸出」 - 本質上就是您的情況。 – cm2 2014-10-18 03:10:04

+0

傑里米的回答不正確;他會後退哪個版本有效,哪些不會,並且沒有發現問題與不刷新標準輸出有關。你的評論「{}」很奇怪;確實,您不必將'{'和'}放在單個語句中,但刪除'{}'當然不是無用的。 – 2014-10-18 04:16:14

2

當您刪除括號,中的printf(「\ r」)語句變成for循環的身體,在邏輯上等價於:

for(;clock() < CLOCKS_PER_SEC;) {printf("\r");} 

所以整數獲得後覆蓋馬上代替延遲期結束。

當然,真正的問題是你爲什麼要使用忙碌循環而不是僅僅調用sleep(1),這會更有效率(即它不會在延遲時間)

+1

刪除括號使程序*工作*,而不是*失敗*,所以這個答案是倒退;真正的問題是,直到打印出'\ r',stdout纔會被刷新。 – 2014-10-18 04:23:49

+0

嗯......好吧,我認爲在這兩種情況下「工作」都不是一個非常準確的術語,因爲程序很忙 - 等待,因此無論哪種方式;然而,在for循環的每一次迭代中執行printf(「\ r」)(在一秒內可能會有數萬次),通過生成許多回車符有效地刷新stdout緩衝區蠻力。 – 2014-10-18 19:50:44

0

在第一個for循環您使用printf的打印值。這裏'printf'使用'stdout',這是一個緩衝輸出 - 除非'\ n'被提供或緩衝區滿,否則不會打印輸出。因此您可以在第一次循環後使用flush(stdout)或使用fprintf(stderr, "")打印到不是緩衝輸出的標準錯誤。

0

這裏是你可能想代碼:

#include <stdio.h> 

int main(int argc, char * argv[]) { 
    int seconds = 10; 

    while(seconds>0) { 
     printf("%10d", --seconds); 
     fflush(stdout); 
     sleep(1); 
     printf("\r"); 
    } 
    printf("%10s\n", "time up!"); 

    return 0; 
} 

(既然你問什麼fflush()acturally就是,這裏是我的理解一點解釋基地)

這是關於io緩存,1原因緩存存在是:讀/寫內存可能比硬盤快1000倍以上。因此,程序應該儘量減少讀/寫硬盤的頻率,並使用內存來代替,但需要對用戶體驗和延遲進行適當的權衡。

例如

  • 當讀取行的文件,它可以讀2KB或所以在一次而不是一個單一的線,然後可以從所述存儲器緩存中讀取,
  • 當寫入到控制檯的程序可能會選擇寫入內存緩存,直到遇到\ n或\ t字符以及其他一些情況。

fflush(FILE *文件),是stdio.h一個函數,它刷新指定文件的緩存。在你的情況下,該文件是標準輸出(標準輸出),它打印到你的控制檯。當您使用printf()打印單個數字時,它可能會寫入stdout的緩存,所以您沒有在控制檯中看到它,但調用fflush(stdout)將緩存清除到控制檯。


+0

我還不明白'fflush(stdout)'。你能向我解釋它到底是什麼嗎? – harianja 2014-10-18 05:46:19

+0

@harianja看到我更新的答案,它解釋了一點,但要真正理解你需要谷歌和書籍及練習來檢查io和緩存。 – 2014-10-18 06:02:08

+0

@harianja當您調用printf時,它將數據存儲在緩衝區中,而不是立即將其寫入文件或終端(這是出於效率原因)。刷新緩衝區將其寫入設備。這種情況發生在緩衝區填滿時,或者當你要求用fflush明確地清空它時,或者對於終端,當寫入一個換行符(或者顯然,在你的系統上是'\ r')時。 – 2014-10-18 07:44:30