C Primer Plus 第8章 字符輸入/輸出和輸入確認 8.3 終止鍵盤輸入

8.3.1  文件、流和鍵盤輸入小程序

文件是一塊存儲信息的存儲器區域。一般,文件被保存在某種類別的永久存儲器上,例如軟盤、硬盤或磁盤。函數

具備強大、靈活等特色的C語言具備許多打開、讀取、寫入和關閉文件的庫函數。在一個級別上,它可使用宿主操做系統的基本文件工具來處理文件。這被稱爲低級I/O。因爲計算機系統之間存在許多差別,因此不可能建立一個通用的低級I/O函數標準庫。然而,C還以第二種級別處理文件,稱爲標準I/O包。這包括建立用於處理文件的I/O函數的標準模型和標準集。工具

使用標準I/O包時,就屏蔽掉了這些差別。所以,要檢查一個換行符,您可使用if(ch=='\n')。若是該系統實際上使用回車/換行字符的組合,則I/O函數自動在兩種表示法之間來回轉換。操作系統

從概念上講,C程序處理一個流而不是直接處理文件。流(stream)是一個理想化的數據流,實際輸入或輸出映射到這個數據流。這意味着具備不一樣屬性的多種類型的輸入由流表示,會具備更多統一的屬性。因而打開文件的過程就成爲將流與文件相關聯,並經過流進行讀寫的過程。unix

第13單詳細的討論了文件。對本章來講,僅需注意C對待輸入和輸出設備與其對待存儲設備上的普通文件相同。特別的是,鍵盤和顯示設備做爲每一個C程序自動打開的文件來對待鍵盤輸入由一個被稱爲stdin的流表示,而到屏幕上的輸出由一個被稱爲stdout的流表示。getchar() putchar() printf() scanf()函數都是標準I/O包的成員。這些函數同這兩個流打交道。code

全部這些的一個結論是可使用與處理文件相同的技術來處理鍵盤輸入。例如,讀取文件的程序須要一種方法來檢測文件的結尾,以 瞭解中止讀取的位置。所以,C輸入函數裝備有一個內置的文件尾檢測器。由於鍵盤輸入是像文件同樣被看待的,因此也應該能使用該文件尾檢測器來終止鍵盤輸入。get

8.3.2  文件結尾io

計算機操做系統須要某種方式來斷定每一個文件起始和結束的位置。檢測文件結尾的一種方法是在文件中放置一個特殊字符來標誌結尾。class

第二種方法是讓操做系統存儲文件大小的信息。若是一個文件具備3000字節,並且程序已經讀取了3000字節,則該程序就到達了文件尾。MS-DOS家庭對二進制文件使用這種方法,由於此方法容許文件擁有包括ctrl+z在內的全部字符。DOS的最新版本對文本文件也使用這種方法。Unix對全部文件都使用此方法。stream

對於這兩種不一樣的方法,C的處理方式是讓getchar()函數在到達文件結尾時返回一個特殊的值而不去管操做系統是如何檢測文件結尾的賦予該值的名稱是EOF(End of file)。所以,檢測到文件尾時,getchar()的返回值是EOF。scanf()函數在檢測到文件結尾時也返回EOF。一般EOF在stdio.h文件中定義:#define EOF (-1)。

爲何是-1?通常狀況下getchar()返回一個範圍在0-127之間的值,由於這些值是與標準字符集相對應的值。但若是系統識別一個擴展的字符集,則可能返回從0-255的值。在每種狀況中,值-1都不對應任何字符,因此能夠用它來表示文件結尾。

一些系統也許將EOF定義爲-1之外的值,但該定義老是與合法的輸入字符所產生的返回值不一樣。若是您包括了stdio.h文件並使用EOF符號,則您就沒必要考慮這個數值的定義。重要的是EOF表明的值表示檢測到文件結尾,這個值並非實際出如今文件中的一個符號

如何在程序中使用EOF呢?將getchar()的返回值與EOF進行比較。若是不相同,則尚未到達文件結尾。換句話說,您可使用以下表達式:

while ((ch=getchar())!=EOF)

若是您讀取的是鍵盤輸入而不是一個文件又會如何?大多數系統具備一種從鍵盤模擬文件結尾條件的方法。瞭解了這一點,您就能夠重寫基本的讀取和回顯程序,如程序清單8.2中所示:

/*echo_eof.c --重複輸入,直到文件的結尾*/
#include <stdio.h>
int main (void)
{
    int ch;

    while((ch=getchar())!=EOF)
        putchar(ch);
    return 0;
}

注意如下幾點:

一、沒必要定義EOF,stdio.h負責定義它;

二、沒必要擔憂EOF的實際值,由於stdio.h中的#define語句使您可以使用EOF進行符號表示。不該編寫假定EOF具備某個特定值的代碼;

三、變量ch從char類型改變爲int類型。這是由於char變量能夠由範圍在0-255中的無符號整數來表示,但EOF可能具備數值-1.該值對無符號char變量是不可能的值,但對int則是可能的。幸運的是getchar()自己的類型其實是int,因此它能夠讀取EOF字符。在使用有符號char類型的實現中,將ch聲明爲char類型仍然是能夠的,但最好是使用更通用的形式。

四、ch是整數的事實不會對putchar()有任何影響。該函數仍打印與其相對應的字符 。

五、要對鍵盤使用此程序,您須要一種鍵入EOF字符的方式。不能簡單的鍵入E\O\F,並且您也不能只鍵入-1.正確的方法是,您必須知道您的系統要求。例如,在大多數unix系統上,在一行的開始鍵入ctrl+D會致使傳送文件尾信號。許多微型計算機系統將一行的開始位置鍵入ctrl+z識別爲文件尾信號,還有一些則把任意位置的ctrl+Z解釋成文件尾信號。

咱們來考慮一下echo_eof.c可能發生的行爲。它把您傳給它的任何輸入都複製到屏幕上。假設您能以某種方式將一個文件傳送給該 程序。它會在屏幕上打印文件的內容,並在發現一個EOF信號即到達文件尾時中止。另外一方面,假設您能找到一種方式將程序的輸出定向到一個文件,您就能夠從鍵盤輸入數據,並使用echo_eof.c來將您鍵入的內容存儲在一個文件中。假設您同時作這兩件事:未來自一個文件的輸入定向到echo_eof.c並將輸出發送到另外一個文件。這樣你尺可使用echo_eof來複制文件。這個小程序具備下列潛在的能力:查看文件內容,建立新文件,以及製做文件副本。關鍵是要控制輸入和輸出流,這就是下一節的話題。

相關文章
相關標籤/搜索