《C語言程序設計》課件第9章_第1頁
《C語言程序設計》課件第9章_第2頁
《C語言程序設計》課件第9章_第3頁
《C語言程序設計》課件第9章_第4頁
《C語言程序設計》課件第9章_第5頁
已閱讀5頁,還剩46頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第9章文件9.1C語言文件系統(tǒng)的基本概念

9.2文件的打開與關閉

9.3文件的讀寫

9.1C語言文件系統(tǒng)的基本概念

9.1.1C文件是流文件

C語言把文件看做是一個字符的序列,即文件是由一個一個字符組成的字符流。因此C語言也將文件稱之為流。

9.1.2C語言支持兩種類型的文件

C語言支持兩種類型的文件:文本文件和二進制文件。這兩種文件的區(qū)別在于存放數(shù)據(jù)的方式不同。文本文件的每一個字節(jié)存放一個ASCII碼,代表一個字符。二進制文件把數(shù)據(jù)以二進制數(shù)的格式存放在文件中,其占用存儲空間較少。C語言對文件的存取是以字符(字節(jié))為單位的,對文件的輸出僅受程序的控制,而不受物理符號(如回車換行符)的控制。9.1.3C語言對文件處理的兩種方法

C語言對文件的處理一般有兩種方法:緩沖文件系統(tǒng)和非緩沖文件系統(tǒng)。在緩沖文件系統(tǒng)中,系統(tǒng)在對文件進行讀寫之前首先在內存區(qū)開辟一個稱做緩沖區(qū)的專用內存區(qū)域。從內存向磁盤寫文件時必須先寫入緩沖區(qū),裝滿緩沖區(qū)后才一起寫到磁盤上去;從磁盤讀文件時必須先將一批數(shù)據(jù)讀到緩沖區(qū)(充滿緩沖區(qū)),然后再從緩沖區(qū)將數(shù)據(jù)逐個送到用戶數(shù)據(jù)區(qū),如圖9.1所示。緩沖區(qū)的大小由各個具體的C語言版本確定,一般為512字節(jié)。圖9.1緩沖文件系統(tǒng)輸入輸出示意圖在非緩沖文件系統(tǒng)中,并不自動開辟大小確定的緩沖區(qū),而是由程序設定緩沖區(qū)的大小。一般地,用緩沖文件系統(tǒng)進行的輸入/輸出稱為高級磁盤輸入/輸出,用非緩沖文件系統(tǒng)進行的輸入/輸出稱為低級(低層)的輸入/輸出。ANSIC標準采用緩沖文件系統(tǒng)。

9.1.4C文件操作的一般方法

在C語言中,文件的基本操作包括文件的打開、文件指針的定位、文件的讀寫、出錯檢測和文件關閉等內容,對一個文件的操作過程一般如圖9.2所示,對文件的各種操作都是通過標準函數(shù)來完成的,所以,學習C語言的文件操作主要是學習掌握有關文件操作的函數(shù)。圖9.2C文件操作的一般過程9.1.5文件類型

緩沖文件系統(tǒng)中,每個被使用文件的有關信息(包括文件當前的讀寫位置、與文件對應的內存緩沖區(qū)地址、緩沖區(qū)中未被處理的字符數(shù)、文件的操作方式等)都要保存在一個“文件信息區(qū)”,為此系統(tǒng)定義了一個文件類型,稱為FILE類型,這實際上是一個結構體類型:9.1.6文件類型指針

有了結構體FILE類型后,可以定義若干個FILE類型的變量以保存相應文件的信息,再定義文件指針變量,指向FILE類型的變量,例如:

FILE*fp1,*fp2;

其中,fp1、fp2就是指向FILE類型結構的兩個指針變量。

在C程序中,通過fp使用變量中的文件信息,從而訪問該文件。也就是說C程序是通過文件指針變量找到與它相關的文件的。

注意:如果有n個文件,一般應設n個指針變量(指向FILE類型結構體的指針變量)以實現(xiàn)對每個文件的訪問。

9.2文件的打開與關閉

9.2.1文件打開

在C語言中,使用fopen函數(shù)來打開文件,fopen函數(shù)的調用格式為

fopen(“文件名”,“文件使用方式”);

其中,文件名是指文件的全名稱,包括相應的路徑、主文件名、擴展文件名(若有);文件使用方式是指打開文件是為讀、寫、追加,以及是二進制文件還是文本文件。

文件的使用方式及其含義如表9.1所示。表9.1文件的使用方式及其含義

fopen函數(shù)執(zhí)行后返回一個FILE類型的指針,通常賦給一個文件指針變量(如fp)。這樣文件指針fp就和被打開的文件聯(lián)系起來了,其后對文件的讀寫就可以通過文件指針fp來進行。例如:

fp=fopen("f1","r");

表示要打開名字為f1的文件,文件使用方式為r(r代表read,即只讀),函數(shù)返回的FILE型指針賦給了指針變量fp,或者說fp指向了文件f1。說明:

(1)如果不能實現(xiàn)“打開”的任務,fopen函數(shù)將會返回一個出錯信息。出錯的原因可能是用“r”方式打開一個并不存在的文件,磁盤出故障,磁盤已滿無法建立新文件等。此時fopen函數(shù)返回一個空指針值NULL(NULL在stdio.h文件中已被定義為0)。

因此,常用下面的方法打開一個文件:即先檢查打開的操作有否出錯,如果有錯就在終端上輸出“不能打開文件”。exit函數(shù)的作用是終止正在調用的過程。

(2)用以上的方式可以打開文本文件或二進制文件,這是ANSIC的規(guī)定,即用同一種緩沖文件系統(tǒng)來處理文本文件和二進制文件。但目前使用的有些C編譯系統(tǒng)可能不完全提供所有這些功能(例如有的只能用?"r"、"w"、"a"?方式),有的C版本不用?"r+"、"w+"、"a+",而用?"rw"、"wr"、"ar"?等,請讀者注意所用系統(tǒng)的規(guī)定。

(3)在向計算機輸入文本文件時,將回車換行符轉換為一個換行符,在輸出時把換行符轉換成為回車和換行兩個字符。而使用二進制文件時,不進行這種轉換,在內存中的數(shù)據(jù)格式與輸出到外部文件中的數(shù)據(jù)格式完全一致。

(4)程序開始運行時,系統(tǒng)自動打開3個標準文件:標準輸入、標準輸出、標準出錯輸出。通常這三個文件都與終端相聯(lián)系。因此以前我們所用到的從終端輸入或輸出都不需要打開終端文件。

【例9.1】

使用fopen函數(shù)打開一個文件。

程序如下:圖9.3例9.1的運行結果9.2.2文件關閉

當一個文件使用完畢后應關閉,以防止再被誤用。

“關閉”就是使文件指針變量不指向該文件,也就是文件指針變量與文件“脫鉤”,此后不能再通過該指針對原來與其相聯(lián)系的文件進行讀寫操作,除非再次打開文件,并使該指針變量重新指向該文件。

用fclose函數(shù)關閉文件。fclose函數(shù)調用的格式為

fclose(文件指針);

例如:

fclose(fp);

fclose函數(shù)調用成功,則返回值為0;否則返回EOF(-1)。EOF是在stdio.h文件中定義的符號常量,值為-1。

為防止文件數(shù)據(jù)丟失,文件使用完畢后必須關閉,特別是對以寫方式打開的文件。

9.3文?件?的?讀?寫

9.3.1字符讀寫函數(shù)

1.寫字符函數(shù)(fputc)

fputc函數(shù)的調用格式為

fputc(字符表達式,文件指針);

fputc函數(shù)的功能是將字符表達式的值輸出到文件指針所指向的文件中去。其中字符表達式指要輸出的字符,它可以是一個字符常量,也可以是一個字符變量?!拔募羔槨笔俏募闹羔樧兞浚拔募羔槨敝赶虻奈募呀?jīng)以寫或讀寫方式打開。

如果輸出成功,則fputc函數(shù)返回輸出的字符;如果輸出失敗,則返回一個EOF。

2.讀字符函數(shù)(fgetc)

fgetc函數(shù)的調用格式為

字符變量=fgetc(文件指針);

fgetc函數(shù)的功能是從“文件指針”指定的文件讀入一個字符,該文件必須是以讀或讀寫方式打開的。

fgetc函數(shù)的返回值為讀入的字符,并賦給字符變量。若調用fgetc函數(shù)讀字符時遇到文件結束符,則函數(shù)返回文件結束標志EOF。

【例9.2】

設在當前目錄下有一個名為gh.txt的文件,其內容為“Ilikeprogramming!”,要求編一程序將該文件中的內容打印在屏幕上。

程序如下:圖9.4例9.2的運行結果9.3.2字符串讀寫函數(shù)

文件的字符串讀寫包括fgets函數(shù)和fputs函數(shù)。

1.讀字符串函數(shù)(fgets)

fgets函數(shù)的調用格式為

fgets(字符數(shù)組名,讀入字符的個數(shù),文件指針);

fgets的功能是從指定文件讀入一個字符串并放到字符數(shù)組中。fgets函數(shù)返回值為字符數(shù)組的首地址。

注意:fgets函數(shù)只能從文件指針指向的文件輸入“讀入字符個數(shù)-1”個字符,然后在最后加一個‘\0’字符,得到的字符串共有“讀入字符個數(shù)”個字符,并且把它們放到字符數(shù)組中。如果在讀完“讀入字符個數(shù)-1”個字符之前遇到換行符或EOF,讀入即結束。

2.寫字符串函數(shù)(fputs)

fputs函數(shù)的調用格式為

fputs(字符串表達式,文件指針);

fputs函數(shù)的作用是將“字符串表達式”表示的字符串寫入到fp指向的文件中去。如:

fputs("China",fp);

其作用是把字符串“China”輸出到fp指向的文件。

fputs函數(shù)中第一個參數(shù)可以是字符串常量、字符數(shù)組名或字符型指針。字符串末尾的‘\0’不輸出。若函數(shù)fputs調用成功,函數(shù)返回值為0;若失敗則函數(shù)的返回值為EOF。

以上兩個函數(shù)類似以前介紹過的gets和puts函數(shù),只是fgets和fputs函數(shù)以指定的文件作為讀寫對象。

【例9.3】

編寫一程序,把從鍵盤輸入的一字符串寫入文件mytest1.txt中,輸入時以字符‘!’作為結束。假定在程序執(zhí)行前,TurboC的子目錄中并沒有mytest1.txt文件。

程序如下:圖9.5使用記事本打開的txt文件內容程序用循環(huán)等待用戶輸入,每一個字符輸入后,程序測試到輸入字符不為?'!',則把該字符讀入字符變量ch,然后寫入fp指定的文件。所有字符輸入完畢后,由于用戶接著輸入了?'!',因此退出循環(huán)。所以本程序首先能夠從鍵盤把字符一個個讀入字符變量,然后寫入到文件中,直到用戶輸入結束符?'!'?后,程序退出循環(huán),執(zhí)行關閉文件函數(shù)關閉文件。

程序運行結果表明用戶的屏幕顯示和記事本文件的內容是完全一致的,如圖9.6所示。圖9.6例9.3的運行結果也可以使用FILE菜單中的Directory子菜單,輸入文件名myteste1.txt并回車,在TC界面顯示該文件的內容,如圖9.7所示。圖9.7使用Directory子菜單顯示的內容

【例9.4】

把數(shù)組中的內容(不包括?'\0'?)輸出到文件指針變量所指的文件中。

程序如下:程序說明:程序用循環(huán)等待用戶輸入,當一個字符串輸入完畢(用戶敲了回車)以后,程序測試到字符數(shù)組中的字符串長度大于0,因此把該字符串寫入fp指定的文件,并且添加上回車符。當?shù)?個字符串輸入完畢,用戶敲了回車以后,程序測試到字符串長度大于0,因此把該字符串又寫入fp指定的文件,同樣也加上回車符。第3串輸入了一個空格,因此形成一個空行。第4串輸入完畢后,由于用戶接著直接敲了回車,因此測試到的字符串長度為0,因此退出循環(huán),程序接著執(zhí)行關閉文件函數(shù)將文件關閉。因此本程序首先能夠從鍵盤把一行一行的字符串讀入字符數(shù)組,然后從數(shù)組中寫入到文件,直到用戶直接敲回車符結束輸入后,程序執(zhí)行關閉文件函數(shù)來關閉文件。用戶的屏幕顯示和記事本文件的內容是完全一致的。程序運行結果如圖9.8所示。圖9.8例9.4的運行結果用戶輸入的內容如圖9.9所示,第3行輸入了一個空格,因此形成一個空行。圖9.9記事本顯示的文件mytest2的內容9.3.3數(shù)據(jù)塊讀寫函數(shù)

1.讀數(shù)據(jù)塊函數(shù)(fread)

fread函數(shù)的調用格式為

fread(指針,數(shù)據(jù)塊大小,數(shù)據(jù)塊數(shù)目,文件指針);

其中“指針”是讀入數(shù)據(jù)的存放地址,輸入的數(shù)據(jù)存入該內存塊;“數(shù)據(jù)塊大小”為要讀寫的字節(jié)數(shù);“數(shù)據(jù)塊數(shù)目”是要讀多少個“數(shù)據(jù)塊大小”的數(shù)據(jù)項,因此一次讀入的字節(jié)數(shù)為:“數(shù)據(jù)塊數(shù)目”ד數(shù)據(jù)塊大小”個字節(jié);“文件指針”指的是已打開的準備讀出數(shù)據(jù)塊的文件。

fread函數(shù)的功能是從“文件指針”指向的文件中讀取“數(shù)據(jù)塊數(shù)目”個“數(shù)據(jù)塊大小”的數(shù)據(jù)塊,并存放到“指針”指定的內存中。

若函數(shù)fread調用成功,則返回值為“數(shù)據(jù)塊數(shù)目”的值;若遇到文件結束或出錯則返回0。

2.寫數(shù)據(jù)塊函數(shù)(fwrite)

fwrite函數(shù)的調用格式為

fwrite(指針,數(shù)據(jù)塊大小,數(shù)據(jù)塊數(shù)目,文件指針);

其中,“指針”是準備輸出數(shù)據(jù)塊的首地址,“數(shù)據(jù)塊大小”、“數(shù)據(jù)塊數(shù)目”的含義同fread函數(shù),“文件指針”指的是已經(jīng)打開的準備寫入數(shù)據(jù)塊的文件。

fwrite函數(shù)的功能為將“指針”指向的內存中的“數(shù)據(jù)塊數(shù)目”ד數(shù)據(jù)塊大小”個字節(jié)內容寫入到“文件指針”指向的文件中。若函數(shù)fwrite調用成功,則返回值為“數(shù)據(jù)塊數(shù)目”的值,即寫入到文件的數(shù)據(jù)塊的個數(shù)。

說明:如果文件以二進制形式打開,用fread和fwrite函數(shù)就可以讀寫任何類型的信息。

【例9.5】

假設一個學生的信息包括姓名、學號、年齡和成績,寫一程序完成從鍵盤讀入4個學生的信息,然后把它們轉存到磁盤文件上去。

問題分析:

(1)根據(jù)要求,學生的信息可以是結構體類型,4個學生信息可以由一個結構體數(shù)組表示。在main函數(shù)中,從終端鍵盤輸入4個學生的數(shù)據(jù),然后調用save函數(shù),將這些數(shù)據(jù)輸出到以“stu_list”命名的磁盤文件中。fwrite函數(shù)的作用是將一個數(shù)據(jù)塊送到stu_list文件中。

設用戶輸入的數(shù)據(jù)為

li80011886

wang80021991

cao80031878

lin80041985

程序運行結果如圖9.10所示。圖9.10例9.5的運行結果9.3.4按指定格式讀寫函數(shù)(fprintf函數(shù)和fscanf函數(shù))

文件按指定格式(格式化)讀寫函數(shù)包括按指定格式(格式化)讀(fscanf)函數(shù)和按指定格式(格式化)寫(fprintf)函數(shù)。

fscanf函數(shù)、fprintf函數(shù)與scanf函數(shù)、printf函數(shù)作用相仿,只是fprintf和fscanf函數(shù)的讀寫對象不是終端而是磁盤文件。它們的調用格式為

fscanf(文件指針,格式字符串,輸入表列);

fprintf(文件指針,格式字符串,輸出表列);

例如:

fprintf(fp,"%d,%6.2f",i,t);它的作用是將整型變量i和實型變量t的值按%d和%6.2f的格式輸出到fp指向的文件上。如果i=3,t=4.5,則輸出到磁盤文件上的是以下的字符串:

3,4.50

再如:

fscanf(fp,"%d,%f",&i,&t);

它的作用是從fp指向的文件中按%d和%f格式讀入數(shù)據(jù)。注意文件中存放的是ASCII碼字符,讀入過程中自動轉換成格式要求的數(shù)據(jù)。

磁盤文件上如果有以下字符:

3,4.5

則將磁盤文件中的字符“3”轉換成整數(shù)3送給變量i,將字符“4.5”轉換成實數(shù)4.5送給變量t。

【例9.6】

文件dmytest1.txt的內容如下:

apple 505.5

pear 402.4

banana 253.0

orange 303.3

要求將文件的內容按變量的形式取出。

程序如下:圖9.11例9.6的運行結果用fprintf和fscanf函數(shù)對磁盤文件讀寫,使用方便、容易理解,但由于在輸入時要將ASCII碼轉換為二進制形式,在輸出時又要將二進制形式轉換成字符,這樣將增加花費的時間。因此,在內存與磁盤頻繁交換數(shù)據(jù)的情況下,最好不用fprintf和fscanf函數(shù),而用fread和fwrite函數(shù)。

9.3.5文件的定位

C文件中有一個位置指針指向當前讀寫的位置。順序讀寫一個文件時,一次讀寫完成后,該位置指針自動指向下一個位置。為了能夠改變讀寫的順序,C語言提供了幾個函數(shù),強制使位置指針指向其他指定的位置。

1.移動位置指針函數(shù)(fseek)

fseek函

溫馨提示

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

評論

0/150

提交評論