C 教材:getchar()putchar()

讓我們再介紹兩個標準的外部函式:getchar()putchar()。 並用它來寫一個簡化的 cat 程式:它從 UNIX 的標準輸入裝置 (Standard Input Device),簡記做 stdin,讀入純文字檔案, 然後將這個檔案的內容,非常忠實地輸出到 stdout 去。


#include <stdio.h>
 
/*  簡化的 UNIX cat 程式,第一版  (mycat0.c) */
main() {
    int c;
 
    c = getchar();
    while (c != EOF) {
        putchar(c);
        c = getchar();
    }
}

getchar() 就是從 stdin 讀入一個字元。 所謂一個字元,其實指的是它的字碼。 如果是 ASCII 碼,則是介於 0 和 127 (含) 之間的整數; 如果是 extended ASCII 或 Latin-1 這類字碼,則是介於 0 和 255 (含) 之間的整數。 如果是中文的 Big-5 碼,則每個字由兩個字碼組成。 我們在這份教材內,一律不考慮超過一個字元的編碼系統:包括中文、日文、Unicode。

getchar() 讀入一個字元之後, 將它的值交給 int 資料型態的變數 c 來儲存。 然後 C 檢查 c 是否等於 EOF。 所謂 EOF 是一個預先定義的符號常數,代表著檔案結束。因此,

while (c != EOF)
其實也就是說,重複執行 STATEMENTS_,直到檔案結束為止。

STATEMENTS_ 所做的事非常單純, 它就是把剛才讀進來的那個字元,照原樣輸出到 stdout 去, 接著再從 stdin 讀下一個字元。 然後檢查它是否為 EOF,如此周而復始,直到檔案結束為止。

putchar() 函式其實要求一個 char 型態的資料。 它將那個資料,當做字元解釋,輸出到螢幕上。 但是 cint 型態的變數, 所以,當我們說 putchar(c); 的時候, 其實做了一次資料轉換:先將 c 的資料從 int 轉到 char, 再交由 putchar() 去輸出。

這個程式非常簡單。但是讀者心中可能疑雲又起,例如:

  1. 既然 getchar() 讀進來的資料只有 8 bits,用 char 型態的變數來儲存就可以了,何必要用 int 變數?
  2. 既然 EOF 是個符號常數,它在哪裡定義的?它的值是多少?
  3. getchar() 怎麼知道什麼時候檔案結束了?
  4. mycat0.c 一點用都沒有嘛,我又不知道怎樣從 C 裡面打開一個檔案來讀。

我們先回答第三個問題,因為它最簡單:你何必要知道? 這就是為什麼 getchar() 要由製作作業系統或 C 編譯器的專業工程師來寫。 只有那些人才需要知道怎麼偵測檔案結束。 我們呢,只管呼叫 getchar() 就好了。 反正檔案結束的時候,它會告訴我們 EOF (End of File)。

我們先不談 EOF 在哪裡定義的?以後您一定會知道。 至於它的值,用

printf("%d\n", EOF);
把它印出來看吧。

後面兩節,專門回答第一和第四個問題。

習題

  1. 實驗
        int c=EOF;
        putchar(c);
    

    看看有什麼結果?
  2. 符號常數 EOF 以 int 資料型態解讀的值是多少?

[BCC16-C]
單維彰 (2000/03/24) ---
[Prev] [Next] [Up]