




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第9章文件9.1C語言文件系統(tǒng)的基本概念
9.2文件的打開與關(guān)閉
9.3文件的讀寫
9.1C語言文件系統(tǒng)的基本概念
9.1.1C文件是流文件
C語言把文件看做是一個(gè)字符的序列,即文件是由一個(gè)一個(gè)字符組成的字符流。因此C語言也將文件稱之為流。
9.1.2C語言支持兩種類型的文件
C語言支持兩種類型的文件:文本文件和二進(jìn)制文件。這兩種文件的區(qū)別在于存放數(shù)據(jù)的方式不同。文本文件的每一個(gè)字節(jié)存放一個(gè)ASCII碼,代表一個(gè)字符。二進(jìn)制文件把數(shù)據(jù)以二進(jìn)制數(shù)的格式存放在文件中,其占用存儲空間較少。C語言對文件的存取是以字符(字節(jié))為單位的,對文件的輸出僅受程序的控制,而不受物理符號(如回車換行符)的控制。9.1.3C語言對文件處理的兩種方法
C語言對文件的處理一般有兩種方法:緩沖文件系統(tǒng)和非緩沖文件系統(tǒng)。在緩沖文件系統(tǒng)中,系統(tǒng)在對文件進(jìn)行讀寫之前首先在內(nèi)存區(qū)開辟一個(gè)稱做緩沖區(qū)的專用內(nèi)存區(qū)域。從內(nèi)存向磁盤寫文件時(shí)必須先寫入緩沖區(qū),裝滿緩沖區(qū)后才一起寫到磁盤上去;從磁盤讀文件時(shí)必須先將一批數(shù)據(jù)讀到緩沖區(qū)(充滿緩沖區(qū)),然后再從緩沖區(qū)將數(shù)據(jù)逐個(gè)送到用戶數(shù)據(jù)區(qū),如圖9.1所示。緩沖區(qū)的大小由各個(gè)具體的C語言版本確定,一般為512字節(jié)。圖9.1緩沖文件系統(tǒng)輸入輸出示意圖在非緩沖文件系統(tǒng)中,并不自動開辟大小確定的緩沖區(qū),而是由程序設(shè)定緩沖區(qū)的大小。一般地,用緩沖文件系統(tǒng)進(jìn)行的輸入/輸出稱為高級磁盤輸入/輸出,用非緩沖文件系統(tǒng)進(jìn)行的輸入/輸出稱為低級(低層)的輸入/輸出。ANSIC標(biāo)準(zhǔn)采用緩沖文件系統(tǒng)。
9.1.4C文件操作的一般方法
在C語言中,文件的基本操作包括文件的打開、文件指針的定位、文件的讀寫、出錯(cuò)檢測和文件關(guān)閉等內(nèi)容,對一個(gè)文件的操作過程一般如圖9.2所示,對文件的各種操作都是通過標(biāo)準(zhǔn)函數(shù)來完成的,所以,學(xué)習(xí)C語言的文件操作主要是學(xué)習(xí)掌握有關(guān)文件操作的函數(shù)。圖9.2C文件操作的一般過程9.1.5文件類型
緩沖文件系統(tǒng)中,每個(gè)被使用文件的有關(guān)信息(包括文件當(dāng)前的讀寫位置、與文件對應(yīng)的內(nèi)存緩沖區(qū)地址、緩沖區(qū)中未被處理的字符數(shù)、文件的操作方式等)都要保存在一個(gè)“文件信息區(qū)”,為此系統(tǒng)定義了一個(gè)文件類型,稱為FILE類型,這實(shí)際上是一個(gè)結(jié)構(gòu)體類型:9.1.6文件類型指針
有了結(jié)構(gòu)體FILE類型后,可以定義若干個(gè)FILE類型的變量以保存相應(yīng)文件的信息,再定義文件指針變量,指向FILE類型的變量,例如:
FILE*fp1,*fp2;
其中,fp1、fp2就是指向FILE類型結(jié)構(gòu)的兩個(gè)指針變量。
在C程序中,通過fp使用變量中的文件信息,從而訪問該文件。也就是說C程序是通過文件指針變量找到與它相關(guān)的文件的。
注意:如果有n個(gè)文件,一般應(yīng)設(shè)n個(gè)指針變量(指向FILE類型結(jié)構(gòu)體的指針變量)以實(shí)現(xiàn)對每個(gè)文件的訪問。
9.2文件的打開與關(guān)閉
9.2.1文件打開
在C語言中,使用fopen函數(shù)來打開文件,fopen函數(shù)的調(diào)用格式為
fopen(“文件名”,“文件使用方式”);
其中,文件名是指文件的全名稱,包括相應(yīng)的路徑、主文件名、擴(kuò)展文件名(若有);文件使用方式是指打開文件是為讀、寫、追加,以及是二進(jìn)制文件還是文本文件。
文件的使用方式及其含義如表9.1所示。表9.1文件的使用方式及其含義
fopen函數(shù)執(zhí)行后返回一個(gè)FILE類型的指針,通常賦給一個(gè)文件指針變量(如fp)。這樣文件指針fp就和被打開的文件聯(lián)系起來了,其后對文件的讀寫就可以通過文件指針fp來進(jìn)行。例如:
fp=fopen("f1","r");
表示要打開名字為f1的文件,文件使用方式為r(r代表read,即只讀),函數(shù)返回的FILE型指針賦給了指針變量fp,或者說fp指向了文件f1。說明:
(1)如果不能實(shí)現(xiàn)“打開”的任務(wù),fopen函數(shù)將會返回一個(gè)出錯(cuò)信息。出錯(cuò)的原因可能是用“r”方式打開一個(gè)并不存在的文件,磁盤出故障,磁盤已滿無法建立新文件等。此時(shí)fopen函數(shù)返回一個(gè)空指針值NULL(NULL在stdio.h文件中已被定義為0)。
因此,常用下面的方法打開一個(gè)文件:即先檢查打開的操作有否出錯(cuò),如果有錯(cuò)就在終端上輸出“不能打開文件”。exit函數(shù)的作用是終止正在調(diào)用的過程。
(2)用以上的方式可以打開文本文件或二進(jìn)制文件,這是ANSIC的規(guī)定,即用同一種緩沖文件系統(tǒng)來處理文本文件和二進(jìn)制文件。但目前使用的有些C編譯系統(tǒng)可能不完全提供所有這些功能(例如有的只能用?"r"、"w"、"a"?方式),有的C版本不用?"r+"、"w+"、"a+",而用?"rw"、"wr"、"ar"?等,請讀者注意所用系統(tǒng)的規(guī)定。
(3)在向計(jì)算機(jī)輸入文本文件時(shí),將回車換行符轉(zhuǎn)換為一個(gè)換行符,在輸出時(shí)把換行符轉(zhuǎn)換成為回車和換行兩個(gè)字符。而使用二進(jìn)制文件時(shí),不進(jìn)行這種轉(zhuǎn)換,在內(nèi)存中的數(shù)據(jù)格式與輸出到外部文件中的數(shù)據(jù)格式完全一致。
(4)程序開始運(yùn)行時(shí),系統(tǒng)自動打開3個(gè)標(biāo)準(zhǔn)文件:標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出、標(biāo)準(zhǔn)出錯(cuò)輸出。通常這三個(gè)文件都與終端相聯(lián)系。因此以前我們所用到的從終端輸入或輸出都不需要打開終端文件。
【例9.1】
使用fopen函數(shù)打開一個(gè)文件。
程序如下:圖9.3例9.1的運(yùn)行結(jié)果9.2.2文件關(guān)閉
當(dāng)一個(gè)文件使用完畢后應(yīng)關(guān)閉,以防止再被誤用。
“關(guān)閉”就是使文件指針變量不指向該文件,也就是文件指針變量與文件“脫鉤”,此后不能再通過該指針對原來與其相聯(lián)系的文件進(jìn)行讀寫操作,除非再次打開文件,并使該指針變量重新指向該文件。
用fclose函數(shù)關(guān)閉文件。fclose函數(shù)調(diào)用的格式為
fclose(文件指針);
例如:
fclose(fp);
fclose函數(shù)調(diào)用成功,則返回值為0;否則返回EOF(-1)。EOF是在stdio.h文件中定義的符號常量,值為-1。
為防止文件數(shù)據(jù)丟失,文件使用完畢后必須關(guān)閉,特別是對以寫方式打開的文件。
9.3文?件?的?讀?寫
9.3.1字符讀寫函數(shù)
1.寫字符函數(shù)(fputc)
fputc函數(shù)的調(diào)用格式為
fputc(字符表達(dá)式,文件指針);
fputc函數(shù)的功能是將字符表達(dá)式的值輸出到文件指針?biāo)赶虻奈募腥?。其中字符表達(dá)式指要輸出的字符,它可以是一個(gè)字符常量,也可以是一個(gè)字符變量?!拔募羔槨笔俏募闹羔樧兞?,“文件指針”指向的文件已經(jīng)以寫或讀寫方式打開。
如果輸出成功,則fputc函數(shù)返回輸出的字符;如果輸出失敗,則返回一個(gè)EOF。
2.讀字符函數(shù)(fgetc)
fgetc函數(shù)的調(diào)用格式為
字符變量=fgetc(文件指針);
fgetc函數(shù)的功能是從“文件指針”指定的文件讀入一個(gè)字符,該文件必須是以讀或讀寫方式打開的。
fgetc函數(shù)的返回值為讀入的字符,并賦給字符變量。若調(diào)用fgetc函數(shù)讀字符時(shí)遇到文件結(jié)束符,則函數(shù)返回文件結(jié)束標(biāo)志EOF。
【例9.2】
設(shè)在當(dāng)前目錄下有一個(gè)名為gh.txt的文件,其內(nèi)容為“Ilikeprogramming!”,要求編一程序?qū)⒃撐募械膬?nèi)容打印在屏幕上。
程序如下:圖9.4例9.2的運(yùn)行結(jié)果9.3.2字符串讀寫函數(shù)
文件的字符串讀寫包括fgets函數(shù)和fputs函數(shù)。
1.讀字符串函數(shù)(fgets)
fgets函數(shù)的調(diào)用格式為
fgets(字符數(shù)組名,讀入字符的個(gè)數(shù),文件指針);
fgets的功能是從指定文件讀入一個(gè)字符串并放到字符數(shù)組中。fgets函數(shù)返回值為字符數(shù)組的首地址。
注意:fgets函數(shù)只能從文件指針指向的文件輸入“讀入字符個(gè)數(shù)-1”個(gè)字符,然后在最后加一個(gè)‘\0’字符,得到的字符串共有“讀入字符個(gè)數(shù)”個(gè)字符,并且把它們放到字符數(shù)組中。如果在讀完“讀入字符個(gè)數(shù)-1”個(gè)字符之前遇到換行符或EOF,讀入即結(jié)束。
2.寫字符串函數(shù)(fputs)
fputs函數(shù)的調(diào)用格式為
fputs(字符串表達(dá)式,文件指針);
fputs函數(shù)的作用是將“字符串表達(dá)式”表示的字符串寫入到fp指向的文件中去。如:
fputs("China",fp);
其作用是把字符串“China”輸出到fp指向的文件。
fputs函數(shù)中第一個(gè)參數(shù)可以是字符串常量、字符數(shù)組名或字符型指針。字符串末尾的‘\0’不輸出。若函數(shù)fputs調(diào)用成功,函數(shù)返回值為0;若失敗則函數(shù)的返回值為EOF。
以上兩個(gè)函數(shù)類似以前介紹過的gets和puts函數(shù),只是fgets和fputs函數(shù)以指定的文件作為讀寫對象。
【例9.3】
編寫一程序,把從鍵盤輸入的一字符串寫入文件mytest1.txt中,輸入時(shí)以字符‘!’作為結(jié)束。假定在程序執(zhí)行前,TurboC的子目錄中并沒有mytest1.txt文件。
程序如下:圖9.5使用記事本打開的txt文件內(nèi)容程序用循環(huán)等待用戶輸入,每一個(gè)字符輸入后,程序測試到輸入字符不為?'!',則把該字符讀入字符變量ch,然后寫入fp指定的文件。所有字符輸入完畢后,由于用戶接著輸入了?'!',因此退出循環(huán)。所以本程序首先能夠從鍵盤把字符一個(gè)個(gè)讀入字符變量,然后寫入到文件中,直到用戶輸入結(jié)束符?'!'?后,程序退出循環(huán),執(zhí)行關(guān)閉文件函數(shù)關(guān)閉文件。
程序運(yùn)行結(jié)果表明用戶的屏幕顯示和記事本文件的內(nèi)容是完全一致的,如圖9.6所示。圖9.6例9.3的運(yùn)行結(jié)果也可以使用FILE菜單中的Directory子菜單,輸入文件名myteste1.txt并回車,在TC界面顯示該文件的內(nèi)容,如圖9.7所示。圖9.7使用Directory子菜單顯示的內(nèi)容
【例9.4】
把數(shù)組中的內(nèi)容(不包括?'\0'?)輸出到文件指針變量所指的文件中。
程序如下:程序說明:程序用循環(huán)等待用戶輸入,當(dāng)一個(gè)字符串輸入完畢(用戶敲了回車)以后,程序測試到字符數(shù)組中的字符串長度大于0,因此把該字符串寫入fp指定的文件,并且添加上回車符。當(dāng)?shù)?個(gè)字符串輸入完畢,用戶敲了回車以后,程序測試到字符串長度大于0,因此把該字符串又寫入fp指定的文件,同樣也加上回車符。第3串輸入了一個(gè)空格,因此形成一個(gè)空行。第4串輸入完畢后,由于用戶接著直接敲了回車,因此測試到的字符串長度為0,因此退出循環(huán),程序接著執(zhí)行關(guān)閉文件函數(shù)將文件關(guān)閉。因此本程序首先能夠從鍵盤把一行一行的字符串讀入字符數(shù)組,然后從數(shù)組中寫入到文件,直到用戶直接敲回車符結(jié)束輸入后,程序執(zhí)行關(guān)閉文件函數(shù)來關(guān)閉文件。用戶的屏幕顯示和記事本文件的內(nèi)容是完全一致的。程序運(yùn)行結(jié)果如圖9.8所示。圖9.8例9.4的運(yùn)行結(jié)果用戶輸入的內(nèi)容如圖9.9所示,第3行輸入了一個(gè)空格,因此形成一個(gè)空行。圖9.9記事本顯示的文件mytest2的內(nèi)容9.3.3數(shù)據(jù)塊讀寫函數(shù)
1.讀數(shù)據(jù)塊函數(shù)(fread)
fread函數(shù)的調(diào)用格式為
fread(指針,數(shù)據(jù)塊大小,數(shù)據(jù)塊數(shù)目,文件指針);
其中“指針”是讀入數(shù)據(jù)的存放地址,輸入的數(shù)據(jù)存入該內(nèi)存塊;“數(shù)據(jù)塊大小”為要讀寫的字節(jié)數(shù);“數(shù)據(jù)塊數(shù)目”是要讀多少個(gè)“數(shù)據(jù)塊大小”的數(shù)據(jù)項(xiàng),因此一次讀入的字節(jié)數(shù)為:“數(shù)據(jù)塊數(shù)目”ד數(shù)據(jù)塊大小”個(gè)字節(jié);“文件指針”指的是已打開的準(zhǔn)備讀出數(shù)據(jù)塊的文件。
fread函數(shù)的功能是從“文件指針”指向的文件中讀取“數(shù)據(jù)塊數(shù)目”個(gè)“數(shù)據(jù)塊大小”的數(shù)據(jù)塊,并存放到“指針”指定的內(nèi)存中。
若函數(shù)fread調(diào)用成功,則返回值為“數(shù)據(jù)塊數(shù)目”的值;若遇到文件結(jié)束或出錯(cuò)則返回0。
2.寫數(shù)據(jù)塊函數(shù)(fwrite)
fwrite函數(shù)的調(diào)用格式為
fwrite(指針,數(shù)據(jù)塊大小,數(shù)據(jù)塊數(shù)目,文件指針);
其中,“指針”是準(zhǔn)備輸出數(shù)據(jù)塊的首地址,“數(shù)據(jù)塊大小”、“數(shù)據(jù)塊數(shù)目”的含義同fread函數(shù),“文件指針”指的是已經(jīng)打開的準(zhǔn)備寫入數(shù)據(jù)塊的文件。
fwrite函數(shù)的功能為將“指針”指向的內(nèi)存中的“數(shù)據(jù)塊數(shù)目”ד數(shù)據(jù)塊大小”個(gè)字節(jié)內(nèi)容寫入到“文件指針”指向的文件中。若函數(shù)fwrite調(diào)用成功,則返回值為“數(shù)據(jù)塊數(shù)目”的值,即寫入到文件的數(shù)據(jù)塊的個(gè)數(shù)。
說明:如果文件以二進(jìn)制形式打開,用fread和fwrite函數(shù)就可以讀寫任何類型的信息。
【例9.5】
假設(shè)一個(gè)學(xué)生的信息包括姓名、學(xué)號、年齡和成績,寫一程序完成從鍵盤讀入4個(gè)學(xué)生的信息,然后把它們轉(zhuǎn)存到磁盤文件上去。
問題分析:
(1)根據(jù)要求,學(xué)生的信息可以是結(jié)構(gòu)體類型,4個(gè)學(xué)生信息可以由一個(gè)結(jié)構(gòu)體數(shù)組表示。在main函數(shù)中,從終端鍵盤輸入4個(gè)學(xué)生的數(shù)據(jù),然后調(diào)用save函數(shù),將這些數(shù)據(jù)輸出到以“stu_list”命名的磁盤文件中。fwrite函數(shù)的作用是將一個(gè)數(shù)據(jù)塊送到stu_list文件中。
設(shè)用戶輸入的數(shù)據(jù)為
li80011886
wang80021991
cao80031878
lin80041985
程序運(yùn)行結(jié)果如圖9.10所示。圖9.10例9.5的運(yùn)行結(jié)果9.3.4按指定格式讀寫函數(shù)(fprintf函數(shù)和fscanf函數(shù))
文件按指定格式(格式化)讀寫函數(shù)包括按指定格式(格式化)讀(fscanf)函數(shù)和按指定格式(格式化)寫(fprintf)函數(shù)。
fscanf函數(shù)、fprintf函數(shù)與scanf函數(shù)、printf函數(shù)作用相仿,只是fprintf和fscanf函數(shù)的讀寫對象不是終端而是磁盤文件。它們的調(diào)用格式為
fscanf(文件指針,格式字符串,輸入表列);
fprintf(文件指針,格式字符串,輸出表列);
例如:
fprintf(fp,"%d,%6.2f",i,t);它的作用是將整型變量i和實(shí)型變量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碼字符,讀入過程中自動轉(zhuǎn)換成格式要求的數(shù)據(jù)。
磁盤文件上如果有以下字符:
3,4.5
則將磁盤文件中的字符“3”轉(zhuǎn)換成整數(shù)3送給變量i,將字符“4.5”轉(zhuǎn)換成實(shí)數(shù)4.5送給變量t。
【例9.6】
文件dmytest1.txt的內(nèi)容如下:
apple 505.5
pear 402.4
banana 253.0
orange 303.3
要求將文件的內(nèi)容按變量的形式取出。
程序如下:圖9.11例9.6的運(yùn)行結(jié)果用fprintf和fscanf函數(shù)對磁盤文件讀寫,使用方便、容易理解,但由于在輸入時(shí)要將ASCII碼轉(zhuǎn)換為二進(jìn)制形式,在輸出時(shí)又要將二進(jìn)制形式轉(zhuǎn)換成字符,這樣將增加花費(fèi)的時(shí)間。因此,在內(nèi)存與磁盤頻繁交換數(shù)據(jù)的情況下,最好不用fprintf和fscanf函數(shù),而用fread和fwrite函數(shù)。
9.3.5文件的定位
C文件中有一個(gè)位置指針指向當(dāng)前讀寫的位置。順序讀寫一個(gè)文件時(shí),一次讀寫完成后,該位置指針自動指向下一個(gè)位置。為了能夠改變讀寫的順序,C語言提供了幾個(gè)函數(shù),強(qiáng)制使位置指針指向其他指定的位置。
1.移動位置指針函數(shù)(fseek)
fseek函
溫馨提示
- 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 公用工程設(shè)備管理制度
- 軟件測試?yán)碚撆c實(shí)踐試題及答案分析
- 數(shù)據(jù)庫遠(yuǎn)程管理技巧試題及答案
- 行政組織理論的變革路徑試題及答案
- 數(shù)據(jù)庫的互聯(lián)互通及其實(shí)施步驟試題及答案
- 計(jì)算機(jī)三級嵌入式設(shè)計(jì)中的注意事項(xiàng)試題及答案
- 云計(jì)算與大數(shù)據(jù)的網(wǎng)絡(luò)架構(gòu)考題及答案
- 行政組織理論的挑戰(zhàn)與機(jī)遇評估試題及答案
- 嵌入式系統(tǒng)中的大數(shù)據(jù)處理技術(shù)試題及答案
- 切實(shí)可行的2025年信息系統(tǒng)監(jiān)理師考試試題及答案
- 2025年成都初三歷史試題及答案
- 2025年公園管理崗面試題及答案
- 學(xué)校食堂 2025 年 2 月食品安全月調(diào)度會議記錄
- 實(shí)習(xí)工作目標(biāo)工作計(jì)劃
- 2025混合交通流環(huán)境下的自動駕駛編隊(duì)仿真測試評價(jià)技術(shù)規(guī)范
- 《銀屑病的診療進(jìn)展》課件
- 2025年官方獸醫(yī)題庫及答案
- 文旅項(xiàng)目策劃案例分析報(bào)告
- 《糖尿病視網(wǎng)膜病變》課件
- 2024年度押運(yùn)服務(wù)收費(fèi)標(biāo)準(zhǔn)及協(xié)議范本3篇
- GB/T 44948-2024鋼質(zhì)模鍛件金屬流線取樣要求及評定
評論
0/150
提交評論