之前在C語言程序統(tǒng)計一個文件的字符數(shù)和 C Primer Plus(5版)第8章編程題1_文件I/O實現(xiàn)1這兩篇文章中,如何實現(xiàn)統(tǒng)計一個文件中的字符個數(shù),我使用了重定向技術和文件I/O函數(shù)來統(tǒng)計的方法。重定向技術簡單,直接調用了系統(tǒng)的能力,所以代碼量也不多。使用fseek和ftell函數(shù)也很簡單,完全使用了這兩個函數(shù)的自身的能力。本文再使用第三種方法,是文件I/O函數(shù)的getc函數(shù)來實現(xiàn)文件字符數(shù)的統(tǒng)計。 一、題目描述本題是第8章編程題的第一道題,題目如下: 二、題目及思路分析從題述來看,有如下幾個關鍵點: 1.有這么一個文本文件 2.讀入文件中的文本 3.統(tǒng)計文件中字符數(shù) 4.判斷文件的結尾 下面再給出這4步的每一步的解決思路。 1. 有這么一個文本文件 這個好解決。我事先準備好了一個文本文件,文件名是author.txt,里面準備了一些字符,如下: weibo: http://weibo.com/520JDH zhihu: http://zhihu.com/people/520WX CSDN: http://blog.csdn.net/kelehaier 2. 打開文件 這是要解決的第一個技術點。使用文件I/O包中的fopen函數(shù)打開文件,最后記得一定要fclose這個文件。 3. 統(tǒng)計文件中字符數(shù) 這是要解決的第二個技術點。如果有一種方法,能夠逐一地讀取每行的每一個字符,并且每讀完一個字符,字符計數(shù)器就自增1,那么我們的目的就達到了。在文件I/O函數(shù)包中, getc函數(shù)就可以達到這個目的。getc函數(shù)的功能是逐一讀取文件中的每一個字符,當然包含每行的結尾的換行符,它需要一個文件指針作為參數(shù)。 4. 判斷文件的結尾 這是要解決的第三個技術點,即,如何判斷getc函數(shù)已經讀到了文件末尾。在C中,針對不同的系統(tǒng),統(tǒng)一以一個“EOF”來表示文件的末尾。這個“EOF”如果你到頭文件中查看其 定義,會看到可能是一個整數(shù)值,比如“-1”。getc()函數(shù)遇到文件末尾后就會返回“EOF”。本程序在getc函數(shù)達到文件末尾后,打印出EOF,看看在我的編譯環(huán)境中EOF的定義值 是什么。 三、代碼實現(xiàn)根據(jù)上述分析,主要代碼如下: pFile = fopen("author.txt","r"); 代碼以文本模式打開文件,getc函數(shù)使用pFile這個文件指針作為參數(shù),從pFile指向的文件中逐一讀取字符,在每讀取一個字符時,計數(shù)器count自增。當文件位置指示器達到文件 末尾時,也就是getc函數(shù)讀到文件末尾時,while循環(huán)退出。此時計數(shù)器count的值便是文件中字符的個數(shù)。由于此時文件位置指示器指向結尾,在退出while循環(huán)后,代碼會將EOF對應的值打出。 四、運行結果本程序的運行環(huán)境如下: OS:Windows XP sp3 編譯器:TDM-GCC 4.9.2 32-bit Release 運行結果如圖: 從運行結果來看,統(tǒng)計出的字符數(shù)是97,并且打印出的EOF的值為-1.在我的編譯環(huán)境中,EOF的值被定義為-1.也許在你的編譯環(huán)境中,EOF的定義值和我不一樣。 現(xiàn)在我將代碼中的文件打開模式修改下,如下: pFile = fopen("author.txt","rb"); 使用二進制模式打開文件,那么再來運行下,看看結果如何: 比較兩種不同的文件打開模式,一個是文本打開模式,一個是二進制打開模式,發(fā)現(xiàn)使用getc函數(shù)統(tǒng)計出的字符數(shù)不一樣! 為了解釋這種現(xiàn)象,我就拿本例的文本文件的第一行的內容“weibo: http://weibo.com/520JDH” 畫個示意圖吧,如下: 這個示意圖是在Windows上,文件內容的存儲方式示意圖??梢钥吹?,一行的換行符其實是由兩個字符組成的:一個是 ,一個是 。如果以二進制模式打開這個文件,那么,對于 getc來說,它將看到兩個字節(jié),一個是“00001101”( 的二進制),一個是“00001010”( 的二進制),因此getc函數(shù)在每行末尾會統(tǒng)計到這兩個字符。 如果以文本模式打開這個文件,那么C實現(xiàn)會做一個轉換,將“ ”兩個字符轉換成一個字符“ ”,我再畫個示意圖如下: 此時getc只能看到一個“00001010”( 的二進制),因此在每行的末尾,getc函數(shù)只會統(tǒng)計到“ ”這一個字符。因此在最終的統(tǒng)計結果中,以文本模式打開統(tǒng)計的字符數(shù)比以二進制模式打開統(tǒng)計的字符數(shù)要少兩個,少的這兩個就是“author.txt”中第一行和第二行末尾的“ ”字符。 由于在linux上,一般而言,一行的結尾只有換行“ ”這一個字符,因此如果運行環(huán)境是linux,那么不管是以文本模式打開還是二進制模式打開,統(tǒng)計到的字符數(shù)都是99.有條件的朋友可以自行試下。 五、技術點本文給出了一種統(tǒng)計文件字符數(shù)的方法,關鍵技術點是getc函數(shù)。如果運行環(huán)境是Win的話,要注意文本模式和二進制模式的區(qū)別。 六、總結目前為止,為了實現(xiàn)統(tǒng)計一個文件中的字符數(shù)的方法,使用了三個不同的技術手段,一個是重定向技術,一個是文件I/O包中的fseek和ftell,最后一個是I/O包中的getc函數(shù)。三種方法各有優(yōu)缺點。朋友們今后需要在自己的項目中實現(xiàn)這一小功能,可以考慮這三種方法。 |
|