C語言第12章文件課件_第1頁
C語言第12章文件課件_第2頁
C語言第12章文件課件_第3頁
C語言第12章文件課件_第4頁
C語言第12章文件課件_第5頁
已閱讀5頁,還剩63頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、C程序設(shè)計C程序設(shè)計 在前面章節(jié)的闡述中,已多次涉及到微型計算機(jī)的輸入輸出操作,這些輸入輸出操作僅對常規(guī)輸入輸出設(shè)備進(jìn)行:從鍵盤輸入數(shù)據(jù),或?qū)?shù)據(jù)從顯示器或打印機(jī)輸出。通過這些常規(guī)輸入輸出設(shè)備,有效地實現(xiàn)了微型計算機(jī)與用戶的聯(lián)系。 第十二章 文 件 在前面章節(jié)的闡述中,已多次涉及到微型計算機(jī)的輸 然而,在實際應(yīng)用系統(tǒng)中,僅僅使用這些常規(guī)外部設(shè)備是很不夠的。使用微型計算機(jī)解決實際問題時往往需要處理大量的數(shù)據(jù);并且希望這些數(shù)據(jù)不僅能被本程序使用,而且也能被其他程序使用。通常在計算機(jī)系統(tǒng)中,一個程序運(yùn)行結(jié)束后,它所占用的內(nèi)存空間將被全部釋放,該程序涉及的各種數(shù)據(jù)所占有的內(nèi)存空間也將被其他程序或數(shù)據(jù)占

2、用而不能被保留。為保存這些數(shù)據(jù),必須將它們以文件形式存儲在外存儲器(如磁盤、磁帶)中;當(dāng)其他程序要使用這些數(shù)據(jù),或該程序還要使用這些數(shù)據(jù)時,再以文件形式將數(shù)據(jù)從外存讀入內(nèi)存。尤其在用戶處理的數(shù)據(jù)量較大,數(shù)據(jù)存儲要求較高,處理功能需求較多的場合,應(yīng)用程序總要使用文件操作功能。 然而,在實際應(yīng)用系統(tǒng)中,僅僅使用這些常規(guī)外部設(shè)備是很12.1 文件概述 12.1.1 文件 從計算機(jī)操作系統(tǒng)的概念看,文件是指存放在外存儲器上的信息的集合。在微型計算機(jī)系統(tǒng)中,使用的外存儲器主要是磁盤。磁盤上的所有信息均以文件的形式存儲,每個文件具有一個唯一的名稱,通過名稱對文件進(jìn)行讀、12.1 文件概述 12.1.1 文

3、件 從計算 寫、修改或刪除等操作。文件的命名方法隨計算機(jī)系統(tǒng)不同而有所差異,在DOS操作系統(tǒng)中文件名稱由文件名和擴(kuò)展名兩部分組成,兩部分之間用“.”號分隔,如:DATAl.C、TURBO.EXE、COMMAND.COM等。規(guī)定文件名最多由8個字符組成,擴(kuò)展名由3個字符組成。 寫、修改或刪除等操作。文件的命名方法隨計算機(jī) 文件可以從不同的角度進(jìn)行分類,例如,按照文件保存的內(nèi)容區(qū)分,磁盤文件可以分為程序文件和數(shù)據(jù)文件。程序文件保存的是程序,數(shù)據(jù)文件用于保存數(shù)據(jù)。程序文件的讀寫操作一般由系統(tǒng)完成,數(shù)據(jù)文件的讀寫往往由應(yīng)用程序?qū)崿F(xiàn)。 文件可以從不同的角度進(jìn)行分類,例如,按照文件 前面用到的計算機(jī)常規(guī)輸

4、入輸出設(shè)備也完成類似的功能,因此,從廣義的角度看,這些外部設(shè)備也都可以看作是一種設(shè)備文件,也可以給它們?nèi)∫粋€唯一的文件名,對它們的操作也可用與磁盤文件相同的方法去完成。 前面用到的計算機(jī)常規(guī)輸入輸出設(shè)備也完 例如,在DOS操作系統(tǒng)中,將打印機(jī)定義成名為PRN的設(shè)備文件,當(dāng)向該文件寫入信息時,實際上就是打印輸出;將鍵盤定義為名字是CON的設(shè)備文件,當(dāng)從該文件讀出信息時,實際上就是從鍵盤接收鍵入的字符。這種將物理設(shè)備看作是一種邏輯文件,用與磁盤文件操作相同的命令進(jìn)行操作的做法,可以簡化程序設(shè)計,方便了用戶。 例如,在DOS操作系統(tǒng)中,將打印 總之,從廣義上說,文件是指信息輸入和輸出的對象,磁盤文件

5、、鍵盤、顯示器、打印機(jī)等均可視為文件。 C語言中采用了類似的做法。C語言中提供了豐富的IO庫函數(shù),利用這些庫函數(shù)完成對各種數(shù)據(jù)文件及設(shè)備文件的操作。 總之,從廣義上說,文件是指信息輸入和輸12.1.2 常用的文件類型 1.文本文件 文本文件又稱ASCII碼文件(也稱字符文件或正文文件),它是由一個個占用一個字節(jié)存儲空間的ASCII字符組成的,每一個字符都被編成ASCII碼存儲,數(shù)據(jù)在內(nèi)存中的表現(xiàn)形式與數(shù)據(jù)本身不一致,必須由系統(tǒng)進(jìn)行一定的轉(zhuǎn)換。正因為每個ASCII碼對應(yīng)一個字符,文本文件的輸出就與字符一一對應(yīng),便于對字符進(jìn)行逐一處理,也便于輸出字符。例如,整數(shù)11111占5個字節(jié)。12.1.2

6、常用的文件類型 1.文本文件 文本文件由文本行組成,每行可含0到多個字符,并以換行符n結(jié)尾,整個文本的結(jié)束標(biāo)志是0 x1a。在用文本向計算機(jī)輸入時,將回車換行符(r和n)轉(zhuǎn)換成一個換行符(n),在輸入時把換行符轉(zhuǎn)換成回車和換行兩個字符。 文本文件由文本行組成,每行可含0到多個字符,2.二進(jìn)制文件 二進(jìn)制文件中的數(shù)據(jù)與其在內(nèi)存中二進(jìn)制表示是一致的,一個字節(jié)不一定表示一個數(shù)據(jù),其在內(nèi)存中的存儲值與數(shù)值本身是相同的。 例如,2978這個整數(shù),在文本文件中用其ASCII碼表示為: 2 9 7 8 505755562.二進(jìn)制文件 二進(jìn)制文件中的數(shù)據(jù)與其在內(nèi)存101110100010它只需要占用2個字節(jié)。

7、 二進(jìn)制文件也不做像文本文件那樣的從回車換行符到換行符之間的轉(zhuǎn)換。 即將數(shù)字表示成對應(yīng)的字符序列。這個整數(shù)有4位數(shù)字,共用了4個字符;一個字符占一個字節(jié),故共用了4個字節(jié)。而在二進(jìn)制文件中,該數(shù)表示成相應(yīng)的二進(jìn)制數(shù)字:101110100010它只需要占用2個字節(jié)。 Turbo C語言規(guī)定,在二進(jìn)制存儲形式中,整型數(shù)用2個字節(jié)表示,長整型用4個字節(jié)表示,實型數(shù)(浮點數(shù))用4個字節(jié)表示,雙精度數(shù)用8個字節(jié)表示。 一般地說,二進(jìn)制文件節(jié)省存儲空間,并且由于在輸入時不需要把字符代碼先轉(zhuǎn)換成二進(jìn)制形式再送入內(nèi)存,在輸出時也不需要把數(shù)據(jù)由二進(jìn)制形式轉(zhuǎn)換為字符代碼再輸出,因而輸入輸出速度快。用戶程序在實用中

8、,從節(jié)省時間和空間的要求考慮,一般選用二進(jìn)制文件。但是如果用戶準(zhǔn)備的數(shù)據(jù)是作為文檔使用閱讀的,則一般使用字符文件,它們可以方便、快捷地通過顯示器或打印機(jī)直接輸出 Turbo C語言規(guī)定,在二進(jìn)制存儲形式中 C語言把所有的外設(shè)當(dāng)作文件對待,這樣的文件稱為設(shè)備文件,并由系統(tǒng)給這些設(shè)備文件命名。例如,前面提過的打印機(jī)的設(shè)備文件名是PRN,向PRN輸出數(shù)據(jù),就是向打印機(jī)輸出打印數(shù)據(jù),C中常用的標(biāo)準(zhǔn)設(shè)備文件名如下: 3.設(shè)備文件和流 CON:鍵盤(或KYBD)CON:顯示器(或SCRN)PRN:打印機(jī)(或LPT1)AUX:異步通信口(或COM1) C語言把所有的外設(shè)當(dāng)作文件對待,這樣的文件稱 另外,系統(tǒng)

9、還命名了三個標(biāo)準(zhǔn)設(shè)備文件的文件結(jié)構(gòu)體指針,如下所示: stdin:標(biāo)準(zhǔn)輸入文件結(jié)構(gòu)體指針(由系統(tǒng)分配為鍵盤) stdout:標(biāo)準(zhǔn)輸出文件結(jié)構(gòu)體指針(由系統(tǒng)分配為顯示器) stderr:標(biāo)準(zhǔn)錯誤輸出文件結(jié)構(gòu)體指針(由系統(tǒng)分配為顯示器) 流(stream)是程序輸入輸出的一個連續(xù)的數(shù)據(jù)序列,它實際上是文件輸入輸出的一種狀態(tài)形式。因此,一個C文件就是一個字節(jié)流或二進(jìn)制流。在C語言中,所有的流均以文件形式出現(xiàn),包括設(shè)備文件,這種文件又稱為流式文件。 另外,系統(tǒng)還命名了三個標(biāo)準(zhǔn)設(shè)備文件的文件結(jié)構(gòu)體指針,12.1.3 C語言的輸入輸出操作 由于相對于內(nèi)存儲器而言,磁盤是慢速設(shè)備。在C語言的文件操作中,如果

10、每向磁盤寫入一個字節(jié)或讀出一個字節(jié)的數(shù)據(jù),都要啟動磁盤操作,將會大大降低系統(tǒng)的效率,而且還會對磁盤驅(qū)動器的使用壽命帶來不利影響。為此在文件系統(tǒng)中往往使用緩沖技術(shù),即系統(tǒng)在內(nèi)存中為每一個正在讀寫的文件開辟一個“緩沖區(qū)”,利用緩沖區(qū)完成文件讀寫操作。12.1.3 C語言的輸入輸出操作 由于相對于 當(dāng)從磁盤文件讀數(shù)據(jù)時,應(yīng)用程序并不直接從磁盤文件讀取數(shù)據(jù),而是先由系統(tǒng)將一批數(shù)據(jù)從磁盤取入內(nèi)存“輸入緩沖區(qū)”中,然后再由應(yīng)用程序的讀操作從緩沖區(qū)依次將數(shù)據(jù)送給程序中的接收變量,供程序處理。其過程如圖12.1a所示。 當(dāng)從磁盤文件讀數(shù)據(jù)時,應(yīng)用程序并不直接從磁盤文磁盤文件內(nèi)存程序數(shù)據(jù)區(qū)緩沖區(qū)磁盤文件(a)

11、讀磁盤文件內(nèi)存程序數(shù)據(jù)區(qū)緩沖區(qū)(b) 寫磁盤文件圖12.1 磁盤文件讀寫操作 磁盤文件內(nèi)存程序緩沖區(qū)磁盤文件(a) 讀磁盤文件內(nèi)存程序緩沖 在向磁盤文件寫入數(shù)據(jù)時,先將程序中有關(guān)變量或表達(dá)式的值送到“輸出緩沖區(qū)”中,待緩沖區(qū)裝滿后,才由系統(tǒng)將緩沖區(qū)的數(shù)據(jù)一次寫入磁盤文件中,如圖12.1b所示。 這種利用緩沖區(qū)將對磁盤文件的頻繁逐次訪問變?yōu)榕吭L問的做法稱為標(biāo)準(zhǔn)文件操作,對應(yīng)的磁盤文件系統(tǒng)稱為緩沖文件系統(tǒng),也稱標(biāo)準(zhǔn)文件系統(tǒng)或高層文件系統(tǒng)。不使用緩沖區(qū)的磁盤文件系統(tǒng)成為非緩沖文件系統(tǒng),也稱非標(biāo)準(zhǔn)文件系統(tǒng)或低層文件系統(tǒng)。 標(biāo)準(zhǔn)文件系統(tǒng)功能強(qiáng),使用方便,由系統(tǒng)代替用戶做了許多事情,提供了許多方便。非標(biāo)

12、準(zhǔn)文件系統(tǒng)則直接依賴于操作系統(tǒng),通過操作系統(tǒng)的功能直接對文件進(jìn)行操作,因而被稱為低層文件系統(tǒng)。 在向磁盤文件寫入數(shù)據(jù)時,先將程序中有關(guān)變量或 用C語言編程時,若使用非標(biāo)準(zhǔn)文件系統(tǒng),要求編程者熟悉操作系統(tǒng),善于利用系統(tǒng)的功能,編程難度大一些,但程序的執(zhí)行效率高,占用內(nèi)存資源較少。新的ANSI標(biāo)準(zhǔn)推薦使用標(biāo)準(zhǔn)文件系統(tǒng)。C語言中,無論是使用標(biāo)準(zhǔn)文件系統(tǒng)還是非標(biāo)準(zhǔn)文件系統(tǒng),都是利用IO庫函數(shù)完成文件操作的。 用C語言編程時,若使用非標(biāo)準(zhǔn)文件系統(tǒng),要求編12.1.4 文件存取方式 C語言中,文件被看作是字節(jié)序列,或稱二進(jìn)制流。即C語言的數(shù)據(jù)文件由順序存放的一連串字節(jié)(字符)組成,沒有記錄的界限,因此,C

13、語言的文件稱作流式文件,文件存取操作的數(shù)據(jù)單位是字節(jié),允許存取一個字節(jié)和任意多個字節(jié),這樣有效地增加了文件操作的靈活性。標(biāo)準(zhǔn)IO提供了4種文件存取方法:(1)讀寫一個字符。(2)讀寫一個字符串,將多個字符組成的字符串寫入文件或從文件中讀出。(3)格式化讀寫,根據(jù)格式控制指定的數(shù)據(jù)格式對數(shù)據(jù)進(jìn)行轉(zhuǎn)換存取。(4)成塊讀寫,也稱作按記錄讀寫。C語言的文件雖然是按字節(jié)流存放,但可以按記錄存取多個字節(jié)的數(shù)據(jù)。12.1.4 文件存取方式 C語言中,文件被 對應(yīng)于以上4種文件存取方式,C語言有相應(yīng)的函數(shù)完成。4種存取方式和C語言的對應(yīng)的函數(shù)關(guān)系如圖12.2所示。文件的字節(jié)流將多個字節(jié)作為一個數(shù)據(jù)存取frea

14、dfwrite字符存取fgetcfputc字符串存取fgetsfputs例如 讀取多個字節(jié)格式存取fscanffprintf例如,將兩個字節(jié)的數(shù)據(jù)作為整數(shù)存取圖12.2 四種文件存取方式與函數(shù) 對應(yīng)于以上4種文件存取方式,C語言有相應(yīng)的函12.2 文件操作 12.2.1 文件結(jié)構(gòu)指針 在C語言程序中當(dāng)建立或調(diào)用一個磁盤文件時,必須了解如下信息:與該文件對應(yīng)的內(nèi)存緩沖區(qū)的地址、文件當(dāng)前的讀寫位置、文件操作的方式、是文本文件還是二進(jìn)制文件、是讀操作還是寫操作等。 標(biāo)準(zhǔn)文件系統(tǒng)為每一個文件開辟一個“文件信息區(qū)”,用于存放上述這些信息?!拔募畔^(qū)”在內(nèi)存中,是一個由系統(tǒng)定義的結(jié)構(gòu)體變量,該變量具有F

15、ILE的數(shù)據(jù)結(jié)構(gòu)。FILE數(shù)據(jù)結(jié)構(gòu)一般定義在stdio.h頭文件中,定義如下: 12.2 文件操作 12.2.1 文件結(jié)構(gòu)指針 type structshor level;unsigned flags;char fd;unsigned char hild;short bsize;unsigned char *buffer;unsigned char *curp;unsigned istemp;short token;FILE;type struct 這是Turbo C中使用的定義,不同的C編譯程序可能使用不同的定義,即結(jié)構(gòu)中的字段名、字段個數(shù)、字段作用等都可能不同,但基本含義變化不會太大,因為

16、它最終都要通過操作系統(tǒng)去控制這些文件。讀者對這些內(nèi)容不必深究。 每當(dāng)程序打開一個文件(若該文件不存在,則表示要建立文件;若文件已存在,則打開就意味著要對該文件進(jìn)行讀寫),系統(tǒng)就在內(nèi)存建立一個與該文件對應(yīng)的FILE結(jié)構(gòu)體變量。有幾個文件就建立幾個這樣的結(jié)構(gòu)體變量,分別存放各文件的有關(guān)信息。同時返回對應(yīng)FILE結(jié)構(gòu)指針(地址)。這樣,對該文件的操作,都以該指針為參考,用戶無需對這個結(jié)構(gòu)的內(nèi)容進(jìn)行控制。 這是Turbo C中使用的定義,不同的C編譯 程序中不用變量名來標(biāo)識結(jié)構(gòu)體變量,而是設(shè)置一個指向該結(jié)構(gòu)體變量的指針變量,通過它來訪問結(jié)構(gòu)體變量,例如: FILE *fp;便定義了一個FILE結(jié)構(gòu)體變

17、量。當(dāng)程序打開一個文件,就得到對應(yīng)FILE結(jié)構(gòu)指針。只要把該指針賦給指針變量fp,fp就指向了這個FILE結(jié)構(gòu)體變量,也就是指向這個文件了。 需要注意的是,不要把文件指針與FILE結(jié)構(gòu)指針混為一談,它們代表兩個不同的地址。文件指針指出了對一個文件當(dāng)前要讀寫的數(shù)據(jù)位置。而FILE結(jié)構(gòu)指針指出已打開的文件所對應(yīng)的FILE結(jié)構(gòu)在內(nèi)存的地址,實際上它本身也包含了文件指針的信息。 程序中不用變量名來標(biāo)識結(jié)構(gòu)體變量,而是設(shè)置一12.2.2 文件的打開 對磁盤文件的操作包括打開文件、讀文件、寫文件、關(guān)閉文件或刪除文件等操作。任何一個文件操作,都必須先打開,后讀或?qū)?讀寫完成后,最后都應(yīng)關(guān)閉文件。 所謂打開文

18、件,是在程序和系統(tǒng)之間建立起聯(lián)系,程序把所要操作的文件的有關(guān)信息,如文件名、文件操作方式(讀、寫或讀寫)等通知給系統(tǒng)。從實質(zhì)上看,打開文件表示將給用戶指定的文件在內(nèi)存分配一個FILE結(jié)構(gòu)區(qū),并將該結(jié)構(gòu)的指針返回給用戶程序,此后用戶程序就可用此FILE指針來實現(xiàn)對指定文件的存取操作。12.2.2 文件的打開 對磁盤文件的操作 C語言程序標(biāo)準(zhǔn)文件的打開操作用fopen( )函數(shù)實現(xiàn),其調(diào)用格式為:FILE *fopen(char *filename,char *mode); fopen( )打開一個filename指向的文件,文件操作方式由mode的值決定。 例如,fopen(“datafile.

19、dat”, “r”);表示打開名為datafile.dat的文件,文件操作方式設(shè)定為“只讀”方式(即只能從文件讀取數(shù)據(jù),不能向文件寫入數(shù)據(jù))。 一般文件名需要用雙引號括起來,文件名中也可以包含用雙反斜線隔開的路徑名。文件操作方式規(guī)定如表12.1所示。 C語言程序標(biāo)準(zhǔn)文件的打開操作用fopen( 表12.1 C語言文件操作方式 文件操作方式 含 義 r(只讀) 為只讀打開一個字符文件 w(只寫) 為只寫打開一個字符文件,文件指針指向文件首部 a(追加) 打開字符文件,指向文件尾在已存在的文件中追加數(shù)據(jù) rb(只讀) 為只讀打開一個二進(jìn)制文件 wb(只寫) 為只寫打開一個二進(jìn)制文件 表12.1 C

20、語言文件操作方式 文件操作方式 含 續(xù)表 ab(追加) 打開二進(jìn)制文件,以向文件追加數(shù)據(jù) r+(讀寫) 以讀寫方式打開一個已存在的字符文件 w+(讀寫) 為讀寫建立一個新的字符文件 a+(讀寫) 為讀寫打開一個字符文件,進(jìn)行追加 rb+(讀寫) 為讀寫打開一個二進(jìn)制文件 wb+(讀寫) 為讀寫建立一個新的二進(jìn)制文件 ab+(讀寫) 為讀寫打開一個二進(jìn)制文件進(jìn)行追加 續(xù)表 ab(追加) 打開二進(jìn)制文件,以向文件追加數(shù)據(jù) 說明:(1)用r方式打開的文件只能在該文件已經(jīng)存在的條件下向計算機(jī)輸入數(shù)據(jù)。(2)用w方式打開的文件只能向該文件寫數(shù)據(jù),并且在該文件不存在的情況下,則建立以指定名字命名的文件,如

21、果已經(jīng)存在該文件,則在打開時刪去該文件,然后重新建立一個新文件。(3)用a方式向文件尾追加新的數(shù)據(jù),要求文件必須首先存在。(4)用r+、w+、a+方式打開的文件即可以用來輸入數(shù)據(jù),也可以用來輸出數(shù)據(jù)。其它原理與前述三點相同。說明:(5)當(dāng)用fopen()函數(shù)成功地打開一個文件時,該函數(shù)將返回一個FILE指針;如果文件打開操作失敗,則函數(shù)返回值是一個NULL空指針。fopen()函數(shù)的返回值應(yīng)當(dāng)立即賦給一個PIlE結(jié)構(gòu)指針變量,以便以后能通過該指針變量來訪問這個文件,否則此函數(shù)的返回值就會丟失而導(dǎo)致程序無法對此文件進(jìn)行操作。 (5)當(dāng)用fopen()函數(shù)成功地打開一個文件時,該函數(shù)將返例如,若想

22、打開filel文件進(jìn)行寫操作,可用下面的方法:FILE *fpIf(fp=fopen(”filel”, ”w)=NULL) printf(”file cannot be opened n”);exit(1);elseprintf(”file opened for writing n”);例如,若想打開filel文件進(jìn)行寫操作,可用下面的方法:12.2.3 關(guān)閉文件 程序?qū)ξ募淖x寫操作完成后,必須關(guān)閉文件。這是因為對打開的磁盤文件進(jìn)行寫入時,若文件緩沖區(qū)的空間未被寫入的內(nèi)容填滿,這些內(nèi)容將不會自動寫入打開的文件中,從而導(dǎo)致內(nèi)容丟失。只有對打開的文件進(jìn)行關(guān)閉操作時,停留在文件緩沖區(qū)的內(nèi)容才能寫到

23、磁盤文件上去,從而保證了文件的完整性。關(guān)閉標(biāo)準(zhǔn)文件用fclose( )函數(shù),函數(shù)說明如下:int fclose(FILE *stream);例如,fclose(fpl);它表示該函數(shù)將關(guān)閉FILE結(jié)構(gòu)指針變量fpl對應(yīng)的文件,并返回一個整數(shù)值。若成功地關(guān)閉了文件,則返回一個0值;否則返回一個非零值。 12.2.3 關(guān)閉文件 程序?qū)ξ募淖x寫12.2.4 文件的讀寫1. 文件的字符讀函數(shù)fgetc( )這類函數(shù)每執(zhí)行一次,只能讀寫文件中的一個字符。從磁盤文件讀取字符的函數(shù)是fgetc( ),其形式為:int fgetc(FILE *stream);例如:ch=fgetc(fp1); 它表示函數(shù)從

24、指針變量fp1指定的文件中讀取一個字符并賦給變量ch,fgete( )函數(shù)的 值就是該字符。這個fp1的值是用fopen( )函數(shù)打開該文件時設(shè)定的。若執(zhí)行fgetc( )函數(shù)時遇到文件結(jié)束符EOF,則函數(shù)返回一個值-1給ch。注意,這個一l并不是函數(shù)讀入的字符值,因為沒有一個字符的ASCII碼為-1,當(dāng)系統(tǒng)判斷出函數(shù)返回文件尾的信息EOF時,它就使函數(shù)的返回值為-l。 12.2.4 文件的讀寫1. 文件的字符讀函數(shù)fgetc(2. 文件的字符寫函數(shù)fputc()將一個字符寫入磁盤文件的函數(shù)是fputc(),其形式為:int fputc(int ch,FILE *stream);函數(shù)把字符變量

25、ch的值寫入到由指針變量fp所指定的文件中。fputc()函數(shù)也有一個函數(shù)返回值。如果執(zhí)行此函數(shù)成功就返回被輸出的字符,否則就返回EOF。2. 文件的字符寫函數(shù)fputc()例12.1 編程實現(xiàn)讀出磁盤文件datafile.txt中的內(nèi)容,將它們顯示在屏幕上。 #include /*包含標(biāo)準(zhǔn)輸入輸出頭文件*/main( )FILE *fp;/*定義FILE結(jié)構(gòu)指針變量*/char ch;例12.1 編程實現(xiàn)讀出磁盤文件datafile.txt中if (fp=fopen(”datafile.txt”, ”r”)=NULL)/*打開并測試文件*/printf(”file cannot be ope

26、nedn”);exit(1);/*若文件打開不成功,退出*/while(ch=fgetc(fp)!=EOF)/*讀文件并測試是否文件尾*/fputc(ch,stdout);/*輸出到標(biāo)準(zhǔn)設(shè)備文件(顯示器)顯示*/fclose(fp);/*關(guān)閉文件*/程序中使用了寫文件函數(shù)fputc(),函數(shù)中使用的指針變量名為stdout,指示使用顯示器設(shè)備文件,因而寫文件的結(jié)果是將字符顯示在顯示器上。if (fp=fopen(”datafile.txt”,例12.2 編程完成:從鍵盤輸入字符后,寫入到磁盤文件datafilel.txt中。#include main( )FILE *fpl;char strl

27、;if(fpl=fopen(”datafilel.txt”, ”w”)=NuLL)/*以只寫方式打開文件,且測試*/例12.2 編程完成:從鍵盤輸入字符后,寫入到磁盤文件daprintf(”file cannot be openedn”);exit(1);/*打開不成功退出*/while(strl=fgetc(stdin)!=n)/*從鍵盤輸入并判斷是否回車*/fpute(strl,fpl);/*寫入到磁盤文件datafilel.txt中*/close(fpl);/*關(guān)閉文件*/該程序以只寫方式打開文件datafilel.txt,在執(zhí)行循環(huán)時,用fgetc()函數(shù)從標(biāo)準(zhǔn)設(shè)備文件stdin(即鍵

28、盤)讀入一個字符,再寫到磁盤文件中。在鍵盤輸入“回車”符后,退出循環(huán)。 應(yīng)該指出,文件讀寫函數(shù)fgetc()和fputc()在實際操作時是對文件緩沖區(qū)進(jìn)行的,并非每一次讀寫一個字符都要啟動磁盤操作。為了編程時書寫方便,一些C版本把fgetc()和fputc()函數(shù)定義為宏名getc()和putc(),即#define getc(fp)fgetc(fp)#define putc(ch,fp)fputc(ch,fp) 應(yīng)該指出,文件讀寫函數(shù)fgetc()和fp 因而getc()和fgetc()功能相同,putc()和fputc()相同。讀者熟悉的getchar()和putchar()函數(shù)其實也是f

29、getc()和fputc()的宏,這時文件結(jié)構(gòu)指針定義為標(biāo)準(zhǔn)輸入stdin和標(biāo)準(zhǔn)輸出stdout,即: #define getchar()fgetc(stdin) #define putchar(c)fputc(c,stdout) 因而getc()和fgetc()功能相同,p3. 文件的字符串讀函數(shù) 這類函數(shù)用于從文件中讀寫字符串,其原型為:char *fgets(char *Str,int n,FILE *stream); 其中,fgets()函數(shù)從指針stream指定的文件中讀取n-1個字符,把它送到由指針str指向的字符數(shù)組中。例如:fgets(databuf,6,fp); 可將fp指定

30、的文件中的5個字符讀到databuf內(nèi)存區(qū)去。databuf可以是定義的字符數(shù)組,也可以是動態(tài)分配的內(nèi)存區(qū)。 3. 文件的字符串讀函數(shù) fgets()讀完指定的n-1個字符后返回。若在讀入n-1個字符完成之前就遇到換行符n或文件結(jié)束符EOF,也將停止讀入。但將遇到的換行符n也作為一個字符送入字符數(shù)組中。fgets()在讀入字符串之后會自動添加一個串結(jié)束符0,因此送入字符數(shù)組中的字符串(包括0在內(nèi))最多為n個字節(jié)。 fgets()函數(shù)執(zhí)行完后,返回一個指向該串的指針,即字符數(shù)組的首地址。如果讀到文件尾或出錯,則返回一個空值NULL。實際編程中,可以用ferror()函數(shù)或feof()函數(shù)來測定是

31、讀出出錯還是到了文件尾。 fgets()讀完指定的n-1個字符后返回。若在讀入n例12.3 編程完成:逐行讀出datafile2.txt文件中的字符并顯示出來。#include main( ) FILE*fp2;char buffer64;if(fp2=fopen(”datafile2.txt”, ”r”)=NULL)/*以只讀方式打開文件,且測試*/printf(”cant open filen”);例12.3 編程完成:逐行讀出datafile2.txt文exit(1);/*打開不成功退出*/while(!feof(fp2)/*測試文件是否結(jié)束*/if(fgets(buffer,64,fp

32、2)!=NULL)/*讀一行字符并測試是否為空*/printf(”%s”,buffer); /*顯示該行字符*/fclose(fp2);/*關(guān)閉文件*/exit(1);/*打開不成功退出*/4.文件的字符串寫函數(shù)fputs() 它的原型為: char *fputs(char *Str,int n,FILE *stream); 函數(shù)fputs()把由str指針指明的字符數(shù)組中的字符串寫入由指針stream指定的文件中。該字符串以空字符0結(jié)束,但此字符將不寫入到文件中去。str指向的字符串也可以用數(shù)組名代替,或用字符串常量代替。例如,c=fputs(”computer0”,fp2); 將把”com

33、puter”字符串寫入由fp2指定的文件中去。該函數(shù)正確執(zhí)行后,將返回寫入的字符數(shù)。當(dāng)出錯時將返回-1。 4.文件的字符串寫函數(shù)fputs()5. 格式化讀寫函數(shù) 在實際應(yīng)用中,應(yīng)用程序有時需要按照規(guī)定的格式進(jìn)行文件讀寫,這時可以利用C語言文件格式化讀寫函數(shù)fscanf()和fprintf()完成。 fscanf()和fprintf()函數(shù)與格式化輸入輸出函數(shù)scanf()和printf()操作功能相似,不同之處是scarf()是從stdin標(biāo)準(zhǔn)輸入設(shè)備(鍵盤)輸入,printf()是向stdout標(biāo)準(zhǔn)輸出設(shè)備(顯示器)輸出;fscanf()和fprintf()則是由文件指針變量指定的文件輸入

34、或是向文件指針指定的文件輸出。當(dāng)文件指針變量定義為stdin和stdout時,這兩個函數(shù)的功能就和scanf()和printf()相同了。 格式化讀寫函數(shù)的調(diào)用格式如下:fscanf(FILE *stream,char *format,);fprintf(FILE *stream,char *format,);5. 格式化讀寫函數(shù) 其中,char*format表示輸入輸出格式控制字符串,格式控制字符串的格式說明與scanf()數(shù)和printf()函數(shù)的格式說明完全相同;表示輸入輸出參量表。例如:fscanf(fp, ”%s%d%f”,&va1l,&var2,&var3); 完成按格式控制字符串

35、sdf規(guī)定的格式,從fp指定的文件中讀取數(shù)據(jù)分別送入變量var1、var2、var3中。例12.4 從鍵盤輸入字符信息及數(shù)組信息后,用格式化方式寫入磁盤文件中。 其中,char*format表示輸入輸出格式控#include main( )FILE *fp6;char str20;int age,i;float sum;if(fp6=fopen(”datafile5.txt”, ”w”)=NULL) /*打開文件*/printf(”File connot be openedn”);#include exit(1);printf(”type str:”);for(i=0;i1)/*輸入字符長度大

36、于1則循環(huán)*/printf(fp6, ”%s%d%f”,str,age,sum);/*寫入磁盤文件*/exit(1);printf(”type str,age,sum:”);scanf(”%s%d%f”,str,&age,&sum);/*輸入姓名、年齡和總成績*/fclose(fp6);/*關(guān)閉文件*/ 程序打開文件成功后,通過循環(huán)將多個數(shù)據(jù)以規(guī)定的格式寫入磁盤文件中。一旦輸入的字符長度不大于l,則退出循環(huán),結(jié)束程序運(yùn)行。printf(”type str,age,sum:”);12.2.5 文件的隨機(jī)讀寫 在C語言的實際應(yīng)用中,常常希望能直接讀寫文件中的某一個數(shù)據(jù)項,而不是按文件的物理順序逐個

37、地讀寫數(shù)據(jù)項。這種可以任意指定讀寫位置的文件操作,稱為隨機(jī)讀寫。從上面的敘述可知,只要能移動文件指針到所需的地方,就可實現(xiàn)文件的隨機(jī)讀寫。C語言提供了多個函數(shù)以實現(xiàn)隨機(jī)操作。 1文件指針定位函數(shù) 實現(xiàn)隨機(jī)文件讀寫操作,首先必須解決定位問題。C語言提供的文件指針定位函數(shù)有三個,其函數(shù)調(diào)用形式分別為: 12.2.5 文件的隨機(jī)讀寫 在C語言的實 在C語言的實際應(yīng)用中,常常希望能直接讀寫文件中的某一個數(shù)據(jù)項,而不是按文件的物理順序逐個地讀寫數(shù)據(jù)項。這種可以任意指定讀寫位置的文件操作,稱為隨機(jī)讀寫。從上面的敘述可知,只要能移動文件指針到所需的地方,就可實現(xiàn)文件的隨機(jī)讀寫。C語言提供了多個函數(shù)以實現(xiàn)隨機(jī)

38、操作。 1.文件指針定位函數(shù) 實現(xiàn)隨機(jī)文件讀寫操作,首先必須解決定位問題。C語言提供的文件指針定位函數(shù)有三個,其函數(shù)調(diào)用形式分別為: 在C語言的實際應(yīng)用中,常常希望能直接讀寫文件int fseek(FILE *stream,long offset,int origin);long ftell(FILE *stream);void rewind(FILE *stream); 這里fseek()函數(shù)的作用是使文件指針移動到所需的位置。stream指定需要操作的文件;origin指明以什么地方為基準(zhǔn)進(jìn)行指針移動,起點位置有如表12.2所示的幾種選擇: int fseek(FILE *stream,l

39、ong of表12.2 指針起始位置及其代表符號 起始點具體位置 符號代表 數(shù)字代表 文件的開頭 SEEK_SET 0 文件指針現(xiàn)行位置 SEEK_CUR 1 文件尾 SEEK_END 2 表12.2 指針起始位置及其代表符號 起始點具體位置 符號offset是位移量,是以origin為基準(zhǔn)指針向前或向后移動的字節(jié)數(shù)。所謂向前是指從文件開頭向文件尾移動的方向;向后則反之。位移量的值如果為負(fù),表示指針向后移動。位移量應(yīng)為long型數(shù)據(jù),這樣當(dāng)文件的長度很長時(例如大于64 K),位移量仍在long型數(shù)據(jù)表示范圍之內(nèi)。 例如:fseek(fp,10L,SEEK_SET);其作用是把文件指針從文件開

40、頭移到第10個字節(jié)處。下面的寫法與其功能是一致的:fseek(fp,10L,0);例如:fseek(fp,-20L,SEEK_END);offset是位移量,是以origin為基準(zhǔn)指針向前或向后 它把文件指針從文件尾向前移動20個字節(jié)。 例如:fseek(fp,-5L,1); 函數(shù)將把文件指針從現(xiàn)行位置往回移動5個字節(jié)。 若fseek()函數(shù)調(diào)用成功,返回值為0;否則返回一個非零值。 函數(shù)ftell()用于得到文件指針離開文件起點的偏移量(即偏移的字節(jié)數(shù))如果函數(shù)調(diào)用出錯(例如該文件不存在),則函數(shù)的返回值是-l。 它把文件指針從文件尾向前移動20個字節(jié)。 rewind()函數(shù)用于把文件指針移

41、到文件的開頭。移動成功時,返回值為0,否則返回一個非零值。 利用fseek()函數(shù)控制文件位置后,也可使用前述文件操作函數(shù)進(jìn)行順序讀寫,但順序讀寫的起始位置不一定是從頭開始,可以通過fseek()函數(shù)設(shè)定。 例12.5 用fseek()函數(shù)完成定位讀操作。#include main( )FILE*fp7;char buf32; rewind()函數(shù)用于把文件指針移到文件的開頭。移動if(fp7=fopen(”datafile7.dat”, ”rb”)=NULL) /*打開文件*/printf(”File connot be openedn”);exit(1);fseek(fp7,64 L,SE

42、EK_SET);/*定位文件指針*/fgets(buf,32,fp7);/*讀字符串送入buf數(shù)組中*/fclose(fp7);/*關(guān)閉文件*/if(fp7=fopen(”datafile7.dat”, 該程序在文件datafile7.dat的第64個字節(jié)處開始,用順序讀函數(shù)fgets()讀出一行字符。2. 文件隨機(jī)讀寫函數(shù) C語言標(biāo)準(zhǔn)文件隨機(jī)讀寫函數(shù)分別為fread()和fwrite(),函數(shù)原型為:int fread(void *ptr, int size, int count, FILE *stream);int fwrite(void *ptr,int size,int count,FILE *stream); 其中:ptr指針指向內(nèi)存緩沖區(qū),count為數(shù)據(jù)項個數(shù),每個數(shù)據(jù)項的長度為size個字節(jié)。stream是文件指針變量。 該程序在文件datafile7.dat的第64個字節(jié) 這兩個函數(shù)實際上是按數(shù)據(jù)項(即數(shù)據(jù)塊)進(jìn)行操作,通過它們可以方便地對程序中的數(shù)組、結(jié)構(gòu)體數(shù)據(jù)進(jìn)行整體輸入輸出。 fread()函數(shù)從文

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論