2012-11-29 27 views
2

這是我第一次在這裏發帖,所以希望這是按預期進行的。我正在做K & R的早期練習之一。其目標是使用getchar()從用戶處獲取一串字符,然後使用putchar()打印它們,但跳過任何額外的空格。我對練習的解決方案效果很好,但我不明白爲什麼。回車和putchar()之後,執行在循環中跳過getchar()?

這裏的程序:

#include <stdio.h> 

int main() 
{ 
    int c, spc; 
    c = 0; 
    spc = 0; 

    while(c != EOF) 
    { 
     c = getchar(); 

     if(c == ' ') 
     { 
      if(spc != 1) 
      { 
       putchar(c); 
       spc = 1; 
      } 
     } 
     if(c != ' ') 
     { 
      spc = 0; 
      putchar(c); 
     } 
    } 
    return 0; 
} 

只有一個循環,當它擊中的getchar()如預期在第一次迭代期間停止執行。一旦回車被按下,程序繼續打印出用戶輸入到緩衝區的任何內容,無需額外的空間 - 正是它應該做的。

但我不明白的是,爲什麼執行不會停止在循環中的每個後續迭代時遇到getchar()。/n字符與它有什麼關係?我注意到它也打印換行符,並且在打印完所有東西后,再次停在getchar()處。那麼,爲什麼在每次迭代開始時都跳過getchar(),同時在緩衝區中打印所有內容?

我一直在玩弄C很長一段時間,但直到最近才努力學習它的'正確'的方式。因爲我有一些經驗,所以你不必貶低你的回答很多(所以,就像你解釋爲一個10歲而不是5歲)。

回答

4

當你輸入東西,然後你回車,所有東西都存儲在內部緩衝區中。所以每次循環執行時,它都會到達getchar誰* 確實*轉到該緩衝區並且拉出單個字符。

但我不明白的是爲什麼執行不與循環

程序停止僅在事件其中getchar中未找到任何事情的每個 後續迭代停止緩衝。 現在\n在這種情況下沒有什麼特別的。這只是一種慣例,即CLI在實現返回之前並不實際「發送」你鍵入的內容(即,你可以點擊退格鍵等)。

+0

所以,你說的是隻有在回車被髮送後才調用getchar()。這是有道理的 - getchar()從緩衝區中抓取下一個字符,每次迭代一次,並且putchar()將它們放下。我是否正確理解這一點? – Regz

+0

@Regz這很準確,是的。但是我會說:getchar被調用,它會阻塞,你輸入一個字符串然後你打回來。現在'getchar'解鎖並且隨後的調用也不會阻止。 – cnicutar

+0

謝謝你清理那個。現在它變得更有意義。 – Regz

0

while (c != EOF)打到EOF後結束。經過一些輸入後嘗試按Ctrl + D

+0

謝謝,但那不是我的問題。我明白EOF是什麼,我理解我的while循環。我只是不明白getchar()是如何工作的。我不知道我可以按Ctrl + D進行EOF,但是,非常感謝。 – Regz