




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、C語言程序設(shè)計,第12章 文 件,電子郵箱:,主講:張馳 淮安信息學(xué)院計算機(jī)科學(xué)與工程系,第12章 文 件,12.1 C文件概述,文件(file)是程序設(shè)計中一個重要的概念。 “文件”一般指存儲在外部介質(zhì)上數(shù)據(jù)的集合。 C語言把文件看作是一個字符(字節(jié))的序列,即由一個一個字符(字節(jié))的數(shù)據(jù)順序組成。根據(jù)數(shù)據(jù)的組織形式,可分為ASCII文件和二進(jìn)制文件。 ASCII文件又稱文本(text)文件,它的每一個字節(jié)放一個ASCII代碼,代表一個字符;二進(jìn)制文件是把內(nèi)存中的數(shù)據(jù)按其在內(nèi)存中的存儲形式原樣輸出到磁盤上存放。 例如:如果有一個整數(shù)10000,在內(nèi)存中占2個字節(jié),如果按ASCII碼形式輸出,
2、則占5個字節(jié),而按二進(jìn)制形式輸出,在磁盤上只占2個字節(jié),見圖所示。 (int占2個字節(jié)、10000有5個符號,用ASCII碼表示要用5個字節(jié)),用ASCII碼形式輸出與字符一一對應(yīng),一個字節(jié)代表一個字符,因而便于對字符進(jìn)行逐個處理,也便于輸出字符。但一般占存儲空間較多,而且要花費轉(zhuǎn)換時間(二進(jìn)制形式與ASCII碼間的轉(zhuǎn)換)。 用二進(jìn)制形式輸出數(shù)值,可以節(jié)省外存空間和轉(zhuǎn)換時間,但一個字節(jié)并不對應(yīng)一個字符,不能直接輸出字符形式。一般中間結(jié)果數(shù)據(jù)需要暫時保存在外存上以后又需要輸入到內(nèi)存的,常用二進(jìn)制文件保存。,一個C文件是一個字節(jié)流或二進(jìn)制流,它把數(shù)據(jù)看作是一連串的字符(字節(jié)),而不考慮記錄的界限。
3、換句話說,C語言中文件并不是由記錄(record)組成的。在C語言中對文件的存取是以字符(字節(jié))為單位的,輸入輸出的數(shù)據(jù)流的開始和結(jié)束僅受程序控制而不受物理符號(如回車換行符)控制,我們把這種文件稱為流式文件。 C語言允許對文件存取一個字符,這就增加了處理的靈活性。,在過去使用的C版本(如UNIX系統(tǒng)下使用的C)有兩種對文件的處理方法:一種叫“緩沖文件系統(tǒng)”,一種叫“非緩沖文件系統(tǒng)”。 “緩沖文件系統(tǒng)”是指系統(tǒng)自動地在內(nèi)存區(qū)為每一個正在使用的文件名開辟一個緩沖區(qū)。從內(nèi)存向磁盤輸出數(shù)據(jù)必須先送到內(nèi)存中的緩沖區(qū),裝滿緩沖區(qū)后才一起送到磁盤去。如果從磁盤向內(nèi)存讀入數(shù)據(jù),則一次從磁盤文件將一批數(shù)據(jù)輸入
4、到內(nèi)存緩沖區(qū)(充滿緩沖區(qū)),然后再從緩沖區(qū)逐個地將數(shù)據(jù)送到程序數(shù)據(jù)區(qū)(給程序變量)。緩沖區(qū)的大小由各個具體的C版本確定,一般為512字節(jié)。 “非緩沖文件系統(tǒng)”是指系統(tǒng)不自動開辟確定大小的緩沖區(qū),而由程序為每個文件設(shè)定緩沖區(qū)。,12.2 文件類型指針,在UNIX系統(tǒng)下,用緩沖文件系統(tǒng)來處理文本文件,用非緩沖文件系統(tǒng)處理二進(jìn)制文件。用緩沖文件系統(tǒng)進(jìn)行的輸入輸出又稱為高級(或高層)磁盤輸入輸出(高層I/O),用非緩沖文件系統(tǒng)進(jìn)行的輸入輸出又稱為低級(低層)輸入輸出系統(tǒng)。 ANSI C標(biāo)準(zhǔn)決定不采用非緩沖文件系統(tǒng),而只采用緩沖文件系統(tǒng)。即既用緩沖文件系統(tǒng)處理文本文件,也用它來處理二進(jìn)制文件。也就是將緩
5、沖文件系統(tǒng)擴(kuò)充為可以處理二進(jìn)制文件。 在C語言中,沒有輸入輸出語句,對文件的讀寫都是用庫函數(shù)來實現(xiàn)的。ANSI規(guī)定了標(biāo)準(zhǔn)輸入輸出函數(shù),用它們對文件進(jìn)行讀寫。,文件指針:每個被使用的文件都在內(nèi)存中開辟一個區(qū),用來存放文件的有關(guān)信息(如文件的名字、文件狀態(tài)及文件當(dāng)前位置等)。這些信息是保存在一個結(jié)構(gòu)體變量中的。該結(jié)構(gòu)體類型是由系統(tǒng)定義的,取名為FILE。,Turbo C在stdio.h文件中有以下的文件類型聲明: typedefstruct short level; /*緩沖區(qū)“滿”或“空”的程度*/ unsigned flags; /*文件狀態(tài)標(biāo)志*/ char fd; /*文件描述符*/ un
6、signed char hold; /*如無緩沖區(qū)不讀取字符*/ short bsize; /*緩沖區(qū)的大小*/ unsigned char *buffer; /*數(shù)據(jù)緩沖區(qū)的位置*/ unsigned char *curp; /*指針,當(dāng)前的指向*/ unsigned istemp; /*臨時文件,指示器*/ short token; /*用于有效性檢查*/ FILE; /*文件類型*/,有了結(jié)構(gòu)體FILE類型之后,可以用它來定義若干個FILE類型的變量,以便存放若干個文件的信息。,例如:可以定義以下FILE類型的數(shù)組。 FILEf5; /*定義結(jié)構(gòu)體數(shù)組f,用來存放5個文件的信息*/ 例如
7、:可以定義文件型指針變量。 FILE*fp;,通過文件指針變量能夠找到與它相關(guān)的文件。,12.3 文件的打開與關(guān)閉,對文件讀寫之前應(yīng)該“打開”該文件,在使用結(jié)束之后應(yīng)“關(guān)閉”該文件。,12.3.1 文件的打開(fopen函數(shù)) fopen函數(shù)的調(diào)用方式通常為: FILE*fp; fp=fopen(文件名,使用文件方式); 例如:FILE *fp; fp=fopen(a1,r); /*雙引號*/ fopen函數(shù)帶回指向a1文件的指針并賦給fp,這樣fp就和文件a1相聯(lián)系了?;蛘哒f,fp指向a1文件。 可以看出,在打開一個文件時,通知給編譯系統(tǒng)以下3個信息: 需要打開的文件名。 使用文件的方式。(
8、見下表) 讓哪一個指針變量指向被打開的文件。,說明: 如果不能實現(xiàn)“打開”的任務(wù),fopen函數(shù)將會帶回一個出錯信息。 此時fopen函數(shù)帶回一個空指針值NULL (NULL在stdio.h文件中已被定義為0) 常用下面的方法打開一個文件: if(fp=fopen(file1“,r)=NULL) printf(cannot open this filen); exit(0); /* 關(guān)閉所有文件,終止正在調(diào)用的過程*/ 在程序開始運行時,系統(tǒng)自動打開3個標(biāo)準(zhǔn)文件:標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出、標(biāo)準(zhǔn)出錯輸出。通常這3個文件都與終端相聯(lián)系。以前我們所用到的從終端輸入或輸出都不需要打開終端文件。系統(tǒng)自動定義了
9、3個文件指針stdin、stdout和stderr,分別指向終端輸入、終端輸出和標(biāo)準(zhǔn)出錯輸出(也從終端輸出)。若程序中指定要從stdin所指的文件輸入數(shù)據(jù),就是指從終端鍵盤輸入數(shù)據(jù)。,12.3.2 文件的關(guān)閉(fclose函數(shù)) 在使用完一個文件后應(yīng)該關(guān)閉它,以防止它再被誤用。 “關(guān)閉”就是使文件指針變量不指向該文件,也就是文件指針變量與文件“脫鉤”,此后不能再通過該指針對原來與其相聯(lián)系的文件進(jìn)行讀寫操作。除非再次打開,使該指針變量重新指向該文件。 fclose函數(shù)調(diào)用的一般形式為: fclose(文件指針); 例如: fclose(fp); 應(yīng)該養(yǎng)成在程序終止之前關(guān)閉所有文件的習(xí)慣,如果不關(guān)
10、閉文件將會丟失數(shù)據(jù)。因為,在向文件寫數(shù)據(jù)時,是先將數(shù)據(jù)輸?shù)骄彌_區(qū),待緩沖區(qū)充滿后才正式輸出給文件。如果當(dāng)數(shù)據(jù)未充滿緩沖區(qū)而程序結(jié)束運行,就會將緩沖區(qū)中的數(shù)據(jù)丟失。用fclose函數(shù)關(guān)閉文件,可以避免這個問題,它先把緩沖區(qū)中的數(shù)據(jù)輸出到磁盤文件,然后才釋放文件指針變量。 fclose函數(shù)也帶回一個值,當(dāng)順利地執(zhí)行了關(guān)閉操作,則返回值為0;否則返回EOF(-1)??梢杂胒error函數(shù)來測試。,12.4 文件的讀寫 文件打開之后,就可以對它進(jìn)行讀寫了。,12.4.1fputc函數(shù)和fgetc函數(shù) (putc函數(shù)和getc函數(shù)) 1fputc函數(shù):把一個字符寫到磁盤文件上去。 其一般調(diào)用形式為: f
11、putc(ch,fp); 其中:ch是要輸出的字符,可以是一個字符常量,也可以是一個字符變量; fp是文件指針變量。 fputc(ch,fp)函數(shù)的作用是將字符(ch的值)輸出到fp所指向的文件中去。 fputc函數(shù)也帶回一個值:如果輸出成功則返回值就是輸出的字符;如果輸出失敗,則返回一個EOF(-1)。EOF是在stdio.h文件中定義的符號常量,值為-1。 putchar是從fputc函數(shù)派生出來的。putchar(c)是stdio.h文件中定義的宏: #defineputchar(c)fputc(c,stdout) stdout是系統(tǒng)定義的文件指針變量,它與終端輸出相連。fputc(c,
12、stdout)的作用是將c的值輸出到終端。用宏putchar(c)比寫fputc(c,stdout)簡單一些,從用戶的角度,可以把putchar(c)看作函數(shù)而不必嚴(yán)格地稱它為宏。,2. fgetc函數(shù):從指定的文件讀入一個字符。 fgetc函數(shù)的調(diào)用形式為: ch=fgetc(fp); 其中:fp為文件型指針變量,ch為字符變量。 fgetc函數(shù)帶回一個字符,賦給ch。 如果在執(zhí)行fgetc函數(shù)讀字符時遇到文件結(jié)束符,函數(shù)返回一個文件結(jié)束標(biāo)志EOF(-1)。 如果想從一個磁盤文件順序讀入字符并在屏幕上顯示出來,可以: ch=fgetc(fp); while(ch!=EOF) putchar(
13、ch); ch=fgetc(fp); ,注意: EOF不是可輸出字符,因此不能在屏幕上顯示。由于字符的ASCII碼不可能出現(xiàn)-1,因此EOF定義為-1是合適的。當(dāng)讀入的字符值等于-1(即EOF)時,表示讀入的已不是正常的字符而是文件結(jié)束符(但以上只適用于讀文本文件的情況) 現(xiàn)在ANSI C已允許用緩沖文件系統(tǒng)處理二進(jìn)制文件,而讀入某一個字節(jié)中的二進(jìn)制數(shù)據(jù)的值有可能是-1,而這又恰好是EOF的值。這就出現(xiàn)了需要讀入有用數(shù)據(jù)而卻被處理為“文件結(jié)束”的情況。為了解決這個問題,ANSI C提供一個feof函數(shù)來判斷文件是否真的結(jié)束。 feof(fp)用來測試fp所指向的文件當(dāng)前狀態(tài)是否“文件結(jié)束”。如
14、果是文件結(jié)束,函數(shù)feof(fp)的值為1(真),否則為0(假)。 如果想順序讀入一個二進(jìn)制文件中的數(shù)據(jù),可以用 while(!feof(fp) c=fgetc(fp); 這種方法也適用于文本文件。,為了書寫方便,系統(tǒng)把fputc和fgetc定義為宏名putc和getc #define putc(ch,fp) fputc(ch,fp) #define getc(fp) fgetc(fp) 這是在stdio.h中定義的。用putc和fputc,用getc和fgetc是一樣的。,12.4.2 fread函數(shù)和fwrite函數(shù) (一般是二進(jìn)制文件,打開任何類型的數(shù)據(jù)) 用來讀寫一個數(shù)據(jù)塊。,它們的一
15、般調(diào)用形式為: fread(buffer,size,count,fp); fwrite(buffer,size,count,fp); 其中:buffer是一個指針(地址)。 對fread來說,它是讀入數(shù)據(jù)的存放地址(起始地址)。 對fwrite來說,是要輸出數(shù)據(jù)的起始地址。 size:要讀寫的字節(jié)數(shù)。 count:要進(jìn)行讀寫多少個size字節(jié)的數(shù)據(jù)項。 fp:文件型指針。,如果文件以二進(jìn)制形式打開,用fread和fwrite函數(shù)就可以讀寫任何類型的信息。 如果fread或fwrite調(diào)用成功,則函數(shù)返回值為count的值,即輸入或輸出數(shù)據(jù)項的完整個數(shù)。,如:fread(f,4,2,fp); /
16、*從fp所指文件讀2次(每次4個字節(jié))數(shù)據(jù),存到數(shù)組f中*/ 其中f是實型數(shù)組名,一個實型變量占4個字節(jié)。 如:有一個如下的結(jié)構(gòu)體類型 structstudent_type char name10; int num; int age; char addr30; stud40; 假設(shè)學(xué)生的數(shù)據(jù)已存放在磁盤文件中,可以用下面的for語句和fread函數(shù)讀入40個學(xué)生的數(shù)據(jù): for(i=0;i40;i+) fread(,12.4.3 fprintf函數(shù)和fscanf函數(shù) 文本文件 printf函數(shù)、scanf函數(shù)讀寫對象是終端。 fprintf函數(shù)、fscanf函數(shù)的讀寫對象是磁盤文件。 它們的一
17、般調(diào)用方式為: fprintf(文件指針,格式字符串,輸出表列); (輸出到磁盤文件上) fscanf(文件指針,格式字符串,輸入表列); (從磁盤文件上讀入) 例如:fprintf(fp,”%d,%6.2f”,i,t); 將兩個值i、t按指定的格式輸出到fp所指向的磁盤文件上 例如:fscanf(fp,”%d,%6.2f”, 從fp所指向的磁盤文件上按指定的格式讀兩個值i、t 用fprintf和fscanf函數(shù)對磁盤文件讀寫,使用方便,容易理解,但由于在輸入時要將ASCII碼轉(zhuǎn)換為二進(jìn)制形式,在輸出時又要將二進(jìn)制形式轉(zhuǎn)換成字符,花費時間比較多。因此,在內(nèi)存與磁盤頻繁交換數(shù)據(jù)的情況下,最好不用
18、fprintf和fscanf函數(shù),而用fread和fwrite函數(shù)。,12.4.4 其他讀寫函數(shù) 1putw和getw函數(shù) 一個字(整數(shù)) 用來對磁盤文件讀寫一個字(整數(shù))。 例如:putw(10,fp); /*將整數(shù)10輸出到fp指向的文件*/ 例如:i=getw(fp); /*從磁盤文件讀一個整數(shù)到內(nèi)存,賦給整型變量i*/ 2讀寫其他類型數(shù)據(jù) 自己定義 3fgets函數(shù)和fputs函數(shù) 一個字符串 fgets的作用是從指定文件讀入一個字符串。 如:fgets(str,n,fp); 其中:n是要得到的字符個數(shù),包括最后0在內(nèi),str是字符數(shù)組*/ 若在讀完n-1個字符之前遇到換行符或EOF,
19、讀入即結(jié)束。 fgets函數(shù)返回值為str的首地址。 fputs函數(shù)的作用是向指定的文件輸出一個字符串。 如:fputs(China,fp); /*把字符串“China”輸出到fp指向的文件*/ 其中:fputs函數(shù)中第一個參數(shù)可以是字符串常量、字符數(shù)組名或字符 型指針。字符串末尾的0 不輸出。 若輸出成功,函數(shù)值為0;失敗時,為EOF。 gets和puts函數(shù) fgets和fputs函數(shù)以指定的文件作為讀寫對象。,12.5 文件的定位,文件中有一個位置指針,指向當(dāng)前讀寫的位置。如果順序讀寫一個文件,每次讀寫一個字符,則讀寫完一個字符后,該位置指針自動移動指向下一個字符位置。如果想改變這樣的規(guī)
20、律,強(qiáng)制使位置指針指向其他指定的位置,可以用有關(guān)函數(shù)。 12.5.1 rewind函數(shù) 返回文件頭 rewind函數(shù)的作用是使位置指針重新返回文件的開頭。 此函數(shù)沒有返回值。 如:rewind(fp); 12.5.2 fseek函數(shù)和隨機(jī)讀寫 一般是二進(jìn)制文件 對流式文件可以進(jìn)行順序讀寫,也可以進(jìn)行隨機(jī)讀寫。關(guān)鍵在于控制文件的位置指針,如果位置指針是按字節(jié)位置順序移動的,就是順序讀寫;如果能將位置指針按需要移動到任意位置,就可以實現(xiàn)隨機(jī)讀寫。 用fseek函數(shù)可以實現(xiàn)改變文件的位置指針。 fseek函數(shù)的調(diào)用形式為: fseek(文件類型指針,位移量,起始點) 其中:“起始點”用0、1、2代替,0“文件開始”,1“當(dāng)前位置”,2“文件末尾”。 “位移量”指以“起始點”為基點,向前移動的字節(jié)數(shù)。 ANSI C和大多數(shù)C版本要求位移量是long型數(shù)據(jù)。,fseek函數(shù)一般用于二進(jìn)制文件,因為文本文件要發(fā)生字符轉(zhuǎn)換,計算位置時往往會發(fā)生混亂。 下面是fseek函數(shù)調(diào)用的幾個例子:(L表示long型) fseek(fp,100L,0); 將位置指針移到離文件頭100個字節(jié)處 fseek(fp,5
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 拱墅區(qū)小學(xué)數(shù)學(xué)試卷
- 高一期末深圳數(shù)學(xué)試卷
- 房山區(qū)高三數(shù)學(xué)試卷
- 高一金太陽數(shù)學(xué)試卷
- 福建英語數(shù)學(xué)試卷
- 2025年03月山東威海市中心醫(yī)院山東省博士后創(chuàng)新實踐基地招聘20人筆試歷年專業(yè)考點(難、易錯點)附帶答案詳解
- 財務(wù)評價培訓(xùn)課件模板
- 2025至2030達(dá)瓦納油行業(yè)市場深度研究與戰(zhàn)略咨詢分析報告
- 阜新實驗月考數(shù)學(xué)試卷
- 東莞市初三題目數(shù)學(xué)試卷
- 通信線路工程施工組織設(shè)計方案【實用文檔】doc
- 護(hù)士注冊健康體檢表下載【可直接打印版本】
- 預(yù)計財務(wù)報表編制及分析課件
- 骨科出科試題帶答案
- 河道基槽土方開挖專項施工方案
- Q∕SY 1347-2010 石油化工蒸汽透平式壓縮機(jī)組節(jié)能監(jiān)測方法
- 現(xiàn)代美國玉米商業(yè)育種的種質(zhì)基礎(chǔ)概要
- GB∕T 4162-2022 鍛軋鋼棒超聲檢測方法
- 中醫(yī)治療室工作制度管理辦法
- 提花裝造工藝技術(shù)培訓(xùn)課程
- 研究實驗報告水火箭.doc
評論
0/150
提交評論