C語(yǔ)言第9章-文件教學(xué)課件_第1頁(yè)
C語(yǔ)言第9章-文件教學(xué)課件_第2頁(yè)
C語(yǔ)言第9章-文件教學(xué)課件_第3頁(yè)
C語(yǔ)言第9章-文件教學(xué)課件_第4頁(yè)
C語(yǔ)言第9章-文件教學(xué)課件_第5頁(yè)
已閱讀5頁(yè),還剩87頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第八章

文件第八章

文件C文件概述文件類型指針文件的打開和關(guān)閉文件的讀寫文件的定位出錯(cuò)的檢測(cè)文件的輸入輸出小結(jié)C文件概述(一)C文件概述(一)C文件概述C文件概述文件(file)是程序設(shè)計(jì)中一個(gè)重要的概念。所謂“文件”一般指存儲(chǔ)在外部介質(zhì)上數(shù)據(jù)的集合。一批數(shù)據(jù)是以文件的形式存放在外部介質(zhì)(如磁盤)上的。操作系統(tǒng)是以文件為單位對(duì)數(shù)據(jù)進(jìn)行管理的,也就是說(shuō),如果想找存在外部介質(zhì)上的數(shù)據(jù),必須先按文件名找到所指定的文件,然后再?gòu)脑撐募凶x取數(shù)據(jù)。要向外部介質(zhì)上存儲(chǔ)數(shù)據(jù)也必須先建立一個(gè)文件(以文件名標(biāo)識(shí)),才能向它輸出數(shù)據(jù)。以前各章中所用到的輸入和輸出,都是以終端為對(duì)象的,即從終端鍵盤輸入數(shù)據(jù),運(yùn)行結(jié)果輸出到終端上。從操作系統(tǒng)的角度看,每一個(gè)與主機(jī)相聯(lián)的輸入輸出設(shè)備都看作是一個(gè)文件。例如,終端鍵盤是輸入文件,顯示屏和打印機(jī)是輸出文件。C文件概述文件(file)是程序設(shè)計(jì)中一個(gè)重要的概念。C文件概述在程序運(yùn)行時(shí),常常需要將一些數(shù)據(jù)(運(yùn)行的最終結(jié)果或中間數(shù)據(jù))輸出到磁盤上存放起來(lái),以后需要時(shí)再?gòu)拇疟P中輸入到計(jì)算機(jī)內(nèi)存。這就要用到磁盤文件。C語(yǔ)言把文件看作是一個(gè)字符(字節(jié))的序列,即由一個(gè)一個(gè)字符(字節(jié))的數(shù)據(jù)順序組成。根據(jù)數(shù)據(jù)的組織形式,可分為ASCII文件和二進(jìn)制文件。ASCII文件又稱文本(text)文件,它的每一個(gè)字節(jié)放一個(gè)ASCII代碼,代表一個(gè)字符。二進(jìn)制文件是把內(nèi)存中的數(shù)據(jù)按其在內(nèi)存中的存儲(chǔ)形式原樣輸出到磁盤上存放。如果有一個(gè)整數(shù)10000,在內(nèi)存中占4個(gè)字節(jié),如果按ASCII碼形式輸出,則占5個(gè)字節(jié),而按二進(jìn)制形式輸出,在磁盤上只占4個(gè)字節(jié)。用ASCII碼形式輸出與字符一一對(duì)應(yīng),一個(gè)字節(jié)代表一個(gè)字符,一個(gè)字節(jié)代表一個(gè)字符,因而便于對(duì)字符進(jìn)行逐個(gè)處理,也便于輸出字符。但一般占存儲(chǔ)空間較多,而且要花費(fèi)轉(zhuǎn)換時(shí)間(二進(jìn)制形式與ASCII碼間的轉(zhuǎn)換)。用二進(jìn)制形式輸出數(shù)值,可以節(jié)省外存空間和轉(zhuǎn)換時(shí)間,但一個(gè)字節(jié)并不對(duì)應(yīng)一個(gè)字符,不能直接輸出字符形式。一般中間結(jié)果數(shù)據(jù)需要暫時(shí)保存在外存上以后又需要輸入到內(nèi)存的,常用二進(jìn)制文件保存。C文件概述在程序運(yùn)行時(shí),常常需要將一些數(shù)據(jù)(運(yùn)行的最終結(jié)果或C文件概述由前所述,一個(gè)C文件是一個(gè)字節(jié)流或二進(jìn)制流。它把數(shù)據(jù)看作是一連串的字符(字節(jié)),而不考慮記錄的界限。換句話說(shuō),C語(yǔ)言中文件并不是由記錄(record)組成的。在C語(yǔ)言中對(duì)文件的存取是以字符(字節(jié))為單位的。輸入輸出的數(shù)據(jù)流的開始和結(jié)束僅受程序控制而不受物理符號(hào)(如回車換行符)控制。也就是說(shuō),在輸出時(shí)不會(huì)自動(dòng)增加回車換行符以作為記錄結(jié)束的標(biāo)志,輸入時(shí)不以回車換行符作為記錄的間隔(事實(shí)上C文件并不由記錄構(gòu)成)。我們把這種文件稱為流式文件。C語(yǔ)言允許對(duì)文件存取一個(gè)字符,這就增加了處理的靈活性。在C語(yǔ)言中,沒(méi)有輸入輸出語(yǔ)句,對(duì)文件的讀寫都是用庫(kù)函數(shù)來(lái)實(shí)現(xiàn)的。ANSI規(guī)定了標(biāo)準(zhǔn)輸入輸出函數(shù),用它們對(duì)文件進(jìn)行讀寫。C文件概述由前所述,一個(gè)C文件是一個(gè)字節(jié)流或二進(jìn)制流。它把數(shù)C文件概述有兩種對(duì)文件的處理方法:一種叫“緩沖文件系統(tǒng)”;一種叫“非緩沖文件系統(tǒng)”。所謂緩沖文件系統(tǒng)是指系統(tǒng)自動(dòng)地在內(nèi)存區(qū)為每一個(gè)正在使用的文件名開辟一個(gè)緩沖區(qū)。從內(nèi)存向磁盤輸出數(shù)據(jù)必須先送到內(nèi)存中的緩沖區(qū),裝滿緩沖區(qū)后才一起送到磁盤去。如果從磁盤向內(nèi)存讀入數(shù)據(jù),則一次從磁盤文件將一批數(shù)據(jù)輸入到內(nèi)存緩沖區(qū)(充滿緩沖區(qū)),然后再?gòu)木彌_區(qū)逐個(gè)地將數(shù)據(jù)送到程序數(shù)據(jù)區(qū)(給程序變量)。如下圖所示。緩沖區(qū)的大小由各個(gè)具體的C版本確定,一般為512字節(jié)。C文件概述有兩種對(duì)文件的處理方法:C語(yǔ)言第9章-文件教學(xué)課件C文件概述所謂“非緩沖文件系統(tǒng)”是指系統(tǒng)不自動(dòng)開辟確定大小的緩沖區(qū),而由程序?yàn)槊總€(gè)文件設(shè)定緩沖區(qū)。在UNIX系統(tǒng)下,用緩沖文件系統(tǒng)來(lái)處理文本文件,用非緩沖文件系統(tǒng)處理二進(jìn)制文件。用緩沖文件系統(tǒng)進(jìn)行的輸入輸出又稱為高級(jí)(或高層)磁盤輸入輸出(高層I/O)。用非緩沖文件系統(tǒng)進(jìn)行的輸入輸出又稱為低級(jí)(低層)輸入輸出系統(tǒng)。ANSIC標(biāo)準(zhǔn)決定不采用非緩沖文件系統(tǒng),而只采用緩沖文件系統(tǒng)。即既用緩沖文件系統(tǒng)處理文本文件,也用它來(lái)處理二進(jìn)制文件。也就是將緩沖文件系統(tǒng)擴(kuò)充為可以處理二進(jìn)制文件。本章只介紹ANSIC規(guī)定的文件系統(tǒng)以及對(duì)它的讀寫。C文件概述所謂“非緩沖文件系統(tǒng)”是指系統(tǒng)不自動(dòng)開辟確定大小的(二)文件類型指針(二)文件類型指針文件類型指針緩沖文件系統(tǒng)中,關(guān)鍵的概念是“文件指針”。每個(gè)被使用的文件都在內(nèi)存中開辟一個(gè)區(qū),用來(lái)存放文件的有關(guān)信息(如文件的名字、文件狀態(tài)及文件當(dāng)前位置等)。這些信息是保存在一個(gè)結(jié)構(gòu)體變量中的。該結(jié)構(gòu)體類型是由系統(tǒng)定義的,取名為FILE。TurboC在stdio.h文件中有以下的文件類型聲明:文件類型指針緩沖文件系統(tǒng)中,關(guān)鍵的概念是“文件指針”。每個(gè)被typedefstruct{ shortlevel;/*緩沖區(qū)“滿”或“空”的程度*/ unsignedflags;/*文件狀態(tài)標(biāo)志*/ charfd;/*文件描述符*/ unsignedcharhold;/*如無(wú)緩沖區(qū)不讀取字符*/ shortbsize;/*緩沖區(qū)的大小*/ unsignedchar*baffer;/*數(shù)據(jù)緩沖區(qū)的位置*/ unsignedar*curp;/*指針,當(dāng)前的指向*/ unsignedistemp;/*臨時(shí)文件,指示器*/ shorttoken;/*用于有效性檢查*/}FILE;typedefstruct文件類型指針可以定義文件型指針變量。如: FILEfp;如果有n個(gè)文件,一般應(yīng)設(shè)n個(gè)指針變量(指向FILE類型結(jié)構(gòu)體的指針變量),使它們分別指向n個(gè)文件(確切地說(shuō)指向存放該文件信息的結(jié)構(gòu)體變量),以實(shí)現(xiàn)對(duì)文件的訪問(wèn)。文件類型指針可以定義文件型指針變量。如:(三)文件的打開與關(guān)閉(三)文件的打開與關(guān)閉文件打開fopen函數(shù)對(duì)文件讀寫之前應(yīng)該“打開”該文件,在使用結(jié)束之后應(yīng)關(guān)閉該文件。ANSIC規(guī)定了標(biāo)準(zhǔn)輸入輸出函數(shù)庫(kù),用fopen()函數(shù)來(lái)實(shí)現(xiàn)打開文件。fopen函數(shù)的調(diào)用方式通常為 FILE*fp; fp=fopen(文件名,使用文件方式);例如: fp=fopen("a1","r");可以看出,在打開一個(gè)文件時(shí),通知給編譯系統(tǒng)以下3個(gè)信息:

①需要打開的文件名,也就是準(zhǔn)備訪問(wèn)的文件的名字。②使用文件的方式(“讀”還是“寫”等)。③讓哪一個(gè)指針變量指向被打開的文件。文件打開fopen函數(shù)對(duì)文件讀寫之前應(yīng)該“打開”該文件,在使文件打開fopen函數(shù)文件使用方式參見(jiàn)書上P333表13-1。說(shuō)明:1)用“r”方式:只讀方式,打開的文件只能用于向計(jì)算機(jī)輸入而不能用作向該文件輸出數(shù)據(jù),而且該文件應(yīng)該已經(jīng)存在,不能用“r”方式打開一個(gè)并不存在的文件(即輸入文件),否則出錯(cuò)。2)用“w”方式:只寫方式,打開的文件只能用于向該文件寫數(shù)據(jù)(即輸出文件),而不能用來(lái)向計(jì)算機(jī)輸入。如果原來(lái)不存在該文件,則在打開時(shí)新建立一個(gè)以指定的名字命名的文件。如果原來(lái)已存在一個(gè)以該文件名命名的文件,則在打開時(shí)將該文件刪去,然后重新建立一個(gè)新文件。文件打開fopen函數(shù)文件使用方式參見(jiàn)書上P333表13-1文件打開fopen函數(shù)3)如果希望向文件末尾添加新的數(shù)據(jù)(不希望刪除原有數(shù)據(jù)),則應(yīng)該用“a”方式打開。但此時(shí)該文件必須已存在,否則將得到出錯(cuò)信息。打開時(shí),位置指針移到文件末尾。4)用“r+”、“w+”、“a+”方式打開的文件既可以用來(lái)輸入數(shù)據(jù),也可以用來(lái)輸出數(shù)據(jù)。用“r+”方式時(shí)該文件應(yīng)該已經(jīng)存在,以便能向計(jì)算機(jī)輸入數(shù)據(jù)。用“w+”方式則新建立一個(gè)文件,先向此文件寫數(shù)據(jù),然后可以讀此文件中的數(shù)據(jù)。用“a+”方式打開的文件,原來(lái)的文件不被刪去,位置指針移到文件末尾,可以添加,也可以讀。文件打開fopen函數(shù)3)如果希望向文件末尾添加新的數(shù)據(jù)(不文件打開fopen函數(shù)5)如果不能實(shí)現(xiàn)“打開”的任務(wù),fopen函數(shù)將會(huì)帶回一個(gè)出錯(cuò)信息。出錯(cuò)的原因可能是用“r”方式打開一個(gè)并不存在的文件;磁盤出故障;磁盤已滿無(wú)法建立新文件等。此時(shí)fopen函數(shù)將帶回一個(gè)空指針值NULL(NULL在stdio.h文件中已被定義為0)。常用下面的方法打開一個(gè)文件: if((fp=fopen("file1","r"))==NULL) { printf("cannotopenthisfile\n"); …… }即先檢查打開的操作有否出錯(cuò),如果有錯(cuò)就在終端上輸出“cannotopenthisfile”。文件打開fopen函數(shù)5)如果不能實(shí)現(xiàn)“打開”的任務(wù),fop文件打開fopen函數(shù)6)用以上方式可以打開文本文件或二進(jìn)制文件,這是ANSIC的規(guī)定,用同一種緩沖文件系統(tǒng)來(lái)處理文本文件和二進(jìn)制文件。但目前使用的有些C編譯系統(tǒng)可能不完全提供所有這些功能(例如有的只能用“r”、“w”、“a”方式),有的C版本不用“r+”、“w+”、“a+”,而用“rw”、“wr”、“ar”等,請(qǐng)讀者注意所用系統(tǒng)的規(guī)定。(7)在向計(jì)算機(jī)輸入文本文件時(shí),將回車換行符轉(zhuǎn)換為一個(gè)換行符,在輸出時(shí)把換行符轉(zhuǎn)換成為回車和換行兩個(gè)字符。在用二進(jìn)制文件時(shí),不進(jìn)行這種轉(zhuǎn)換,在內(nèi)存中的數(shù)據(jù)形式與輸出到外部文件中的數(shù)據(jù)形式完全一致,一一對(duì)應(yīng)。文件打開fopen函數(shù)6)用以上方式可以打開文本文件或二進(jìn)制文件打開fopen函數(shù)8)在程序開始運(yùn)行時(shí),系統(tǒng)自動(dòng)打開3個(gè)標(biāo)準(zhǔn)文件:標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出、標(biāo)準(zhǔn)出錯(cuò)輸出。通常這3個(gè)文件都與終端相聯(lián)系。因此以前我們所用到的從終端輸入或輸出都不需要打開終端文件。系統(tǒng)自動(dòng)定義了3個(gè)文件指針stdin、stdout和stderr,分別指向終端輸入、終端輸出和標(biāo)準(zhǔn)出錯(cuò)輸?也從終端輸出)。如果程序中指定要從stdin所指的文件輸入數(shù)據(jù),就是指從終端鍵盤輸入數(shù)據(jù)。文件打開fopen函數(shù)8)在程序開始運(yùn)行時(shí),系統(tǒng)自動(dòng)打開3個(gè)文件關(guān)閉fclose函數(shù)在使用完一個(gè)文件后應(yīng)該關(guān)閉它,以防止它再被誤用。“關(guān)閉”就是使文件指針變量不指向該文件,也就是文件指針變量與文件“脫鉤”,此后不能再通過(guò)該指針對(duì)原來(lái)與其相聯(lián)系的文件進(jìn)行讀寫操作。除非再次打開,使該指針變量重新指向該文件。用fclose函數(shù)關(guān)閉文件。fclose函數(shù)調(diào)用的一般形式為 fclose(文件指針);例如: fclose(fp);fclose函數(shù)也帶回一個(gè)值,當(dāng)順利地執(zhí)行了關(guān)閉操作,則返回值為0;否則返回EOF(-1)。文件關(guān)閉fclose函數(shù)在使用完一個(gè)文件后應(yīng)該關(guān)閉它,以防止文件關(guān)閉fclose函數(shù)應(yīng)該養(yǎng)成在程序終止之前關(guān)閉所有文件的習(xí)慣,如果不關(guān)閉文件將會(huì)丟失數(shù)據(jù)。因?yàn)?,如前所述,在向文件寫?shù)據(jù)時(shí),是先將數(shù)據(jù)輸?shù)骄彌_區(qū),待緩沖區(qū)充滿后才正式輸出給文件。如果當(dāng)數(shù)據(jù)未充滿緩沖區(qū)而程序結(jié)束運(yùn)行,就會(huì)將緩沖區(qū)中的數(shù)據(jù)丟失。用fclose函數(shù)關(guān)閉文件,可以避免這個(gè)問(wèn)題,它先把緩沖區(qū)中的數(shù)據(jù)輸出到磁盤文件,然后才釋放文件指針變量。文件關(guān)閉fclose函數(shù)應(yīng)該養(yǎng)成在程序終止之前關(guān)閉所有文件的(四)文件的讀寫(四)文件的讀寫fputc寫文件函數(shù)把一個(gè)字符寫到磁盤文件上去。其一般調(diào)用形式為: fputc(ch,fp);其中:ch是要輸出的字符,它可以是一個(gè)字符常量,也可以是一個(gè)字符變量。fp是文件指針變量。fputc(ch,fp)函數(shù)的作用是將字符(ch的值)輸出到fp所指向的文件中去。fputc函數(shù)也帶回一個(gè)值:如果輸出成功則返回值就是輸出的字符;如果輸出失敗,則返回一個(gè)EOF(-1)。EOF是在stdio.h文件中定義的符號(hào)常量,值為-1。fputc寫文件函數(shù)把一個(gè)字符寫到磁盤文件上去。其一般調(diào)用形fputc寫文件函數(shù)在前面介紹過(guò)putchar函數(shù),其實(shí)putchar是從fputc函數(shù)派生出來(lái)的。putchar(c)是在stdio.h文件中用預(yù)處理命令#define定義的宏:#defineputchar(c)fputc(c,stdout)前面已敘述,stdout是系統(tǒng)定義的文件指針變量,它與終端輸出相連。fputc(c,stdout)的作用是將c的值輸出到終端。用宏putchar(c)比寫fputc(c,stdout)簡(jiǎn)單一些。從用戶的角度,可以把putchar(c)看作函數(shù)而不必嚴(yán)格地稱它為宏。fputc寫文件函數(shù)在前面介紹過(guò)putchar函數(shù),其實(shí)pufgetc讀文件函數(shù)從指定的文件讀入一個(gè)字符,該文件必須是以讀或讀寫方式打開的。fgetc函數(shù)的調(diào)用形式為 ch=fgetc(fp);fp為文件型指針變量,ch為字符變量。fgetc函數(shù)帶回一個(gè)字符,賦給ch。如果在執(zhí)行fgetc函數(shù)讀字符時(shí)遇到文件結(jié)束符,函數(shù)返回一個(gè)文件結(jié)束標(biāo)志EOF(-1)。如果想從一個(gè)磁盤文件順序讀入字符并在屏幕上顯示出來(lái),可以: ch=fgetc(fp); while(ch!=EOF) { putchar(ch); ch=fgetc(fp);}fgetc讀文件函數(shù)從指定的文件讀入一個(gè)字符,該文件必須是以feof()判斷文件是否結(jié)束函數(shù)注意:EOF不是可輸出字符,因此不能在屏幕上顯示。由于字符的ASCII碼不可能出現(xiàn)-1,因此EOF定義為-1是合適的。當(dāng)讀入的字符值等于-1(即EOF)時(shí),表示讀入的已不是正常的字符而是文件結(jié)束符。但以上只適用于讀文本文件的情況?,F(xiàn)在ANSIC已允許用緩沖文件系統(tǒng)處理二進(jìn)制文件,而讀入某一個(gè)字節(jié)中的二進(jìn)制數(shù)據(jù)的值有可能是-1,而這又恰好是EOF的值。這就出現(xiàn)了需要讀入有用數(shù)據(jù)而卻被處理為“文件結(jié)束”的情況。為了解決這個(gè)問(wèn)題,ANSIC提供一個(gè)feof函數(shù)來(lái)判斷文件是否真的結(jié)束。 feof(fp)用來(lái)測(cè)試fp所指向的文件當(dāng)前狀態(tài)是否“文件結(jié)束”。如果是文件結(jié)束,函數(shù)feof(fp)的值為1(真),否則為0(假)。feof()判斷文件是否結(jié)束函數(shù)注意:EOF不是可輸出字符,feof()判斷文件是否結(jié)束函數(shù)如: while(!feof(fp)) { c=fgetc(fp); …}feof()判斷文件是否結(jié)束函數(shù)如:fputc和fgetc舉例例12.1從鍵盤輸入一些字符,逐個(gè)把它們送到磁盤上去,直到輸入一個(gè)“#”為止。源碼參見(jiàn)12-1.c例12.2將一個(gè)磁盤文件中的信息復(fù)制到另一個(gè)磁盤文件中。源碼參見(jiàn)12-2\a.c使用命令行方式輸入兩個(gè)文件名;源碼參見(jiàn)12-2\b.cfputc和fgetc舉例例12.1從鍵盤輸入一些字符,逐fread和fwrite函數(shù)ANSIC標(biāo)準(zhǔn)提出設(shè)置兩個(gè)函數(shù)(fread和fwrite),用來(lái)讀寫一個(gè)數(shù)據(jù)塊。它們的一般調(diào)用形式為 fread(buffer,size,count,fp); fwrite(buffer,size,count,fp);其中:buffer:是一個(gè)指針。對(duì)fread來(lái)說(shuō),它是讀入數(shù)據(jù)的存放地址。對(duì)fwrite來(lái)說(shuō),是要輸出數(shù)據(jù)的地址(以上指的是起始地址)。size:要讀寫的字節(jié)數(shù)。count:要進(jìn)行讀寫多少個(gè)size字節(jié)的數(shù)據(jù)項(xiàng)。fp:文件型指針。如果fread或fwrite調(diào)用成功,則函數(shù)返回值為count的值,即輸入或輸出數(shù)據(jù)項(xiàng)的完整個(gè)數(shù)。fread和fwrite函數(shù)ANSIC標(biāo)準(zhǔn)提出設(shè)置兩個(gè)函數(shù)fread和fwrite函數(shù)如果文件以二進(jìn)制形式打開,用fread和fwrite函數(shù)就可以讀寫任何類型的信息,如: fread(f,4,2,fp);其中f是一個(gè)實(shí)型數(shù)組名。一個(gè)實(shí)型變量占4個(gè)字節(jié)。這個(gè)函數(shù)從fp所指向的文件讀入2次(每次4個(gè)字節(jié))數(shù)據(jù),存儲(chǔ)到數(shù)組f中。fread和fwrite函數(shù)如果文件以二進(jìn)制形式打開,用frfread和fwrite函數(shù)如果有一個(gè)如下的結(jié)構(gòu)體類型: structstudent-type { charname[10]; intnum; intage; charaddr[30]; }stud[40];假設(shè)學(xué)生的數(shù)據(jù)已存放在磁盤文件中,可以用下面的for語(yǔ)句和fread函數(shù)讀入40個(gè)學(xué)生的數(shù)據(jù): for(i=0;i<40;i++) { fread(&stud[i],sizeof(structstudent-type),1,fp); }同樣,以下for語(yǔ)句和fwrite函數(shù)可以將內(nèi)存中的學(xué)生數(shù)據(jù)輸出到磁盤文件中去: for(i=0;i<40,i++) { fwrite(&stud[i],sizeof(structstudent-type),1,fp); }fread和fwrite函數(shù)如果有一個(gè)如下的結(jié)構(gòu)體類型:fread和fwrite函數(shù)舉例例12.3從鍵盤輸入4個(gè)學(xué)生的有關(guān)數(shù)據(jù),然后把它們轉(zhuǎn)存到磁盤文件上去。源碼參見(jiàn)12-3fread和fwrite函數(shù)舉例例12.3從鍵盤輸入4個(gè)學(xué)其它讀寫函數(shù)自學(xué)。其它讀寫函數(shù)自學(xué)。(五)文件的定位(五)文件的定位文件中有一個(gè)位置指針,指向當(dāng)前讀寫的位置。如果順序讀寫一個(gè)文件,每次讀寫一個(gè)字符,則讀寫完一個(gè)字符后,該位置指針自動(dòng)移動(dòng)指向下一個(gè)字符位置。如果想改變這樣的規(guī)律,強(qiáng)制使位置指針指向其他指定的位置,可以用有關(guān)函數(shù)。文件中有一個(gè)位置指針,指向當(dāng)前讀寫的位置。如果順序讀寫一個(gè)文rewind函數(shù)rewind函數(shù)的作用是使位置指針重新返回文件的開頭。此函數(shù)沒(méi)有返回值。例12.4有一個(gè)磁盤文件,第一次將它的內(nèi)容顯示在屏幕上,第二次把它復(fù)制到另一文件上。源碼參見(jiàn)12-4.crewind函數(shù)rewind函數(shù)的作用是使位置指針重新返回文fseek函數(shù)和隨機(jī)讀寫對(duì)流式文件可以進(jìn)行順序讀寫,也可以進(jìn)行隨機(jī)讀寫。關(guān)鍵在于控制文件的位置指針,如果位置指針是按字節(jié)位置順序移動(dòng)的,就是順序讀寫。如果能將位置指針按需要移動(dòng)到任意位置,就可以實(shí)現(xiàn)隨機(jī)讀寫。所謂隨機(jī)讀寫,是指讀寫完上一個(gè)字符(字節(jié))后,并不一定要讀寫其后續(xù)的字符(字節(jié)),而可以讀寫文件中任意所需的字符(字節(jié))。用fseek函數(shù)可以實(shí)現(xiàn)改變文件的位置指針。fseek函數(shù)和隨機(jī)讀寫對(duì)流式文件可以進(jìn)行順序讀寫,也可以進(jìn)fseek函數(shù)和隨機(jī)讀寫fseek函數(shù)的調(diào)用形式為: fseek(文件類型指針,位移量,起始點(diǎn))其中:“起始點(diǎn)”用0、1或2代替,0代表“文件開始”,1為“當(dāng)前位置”,2為“文件末尾”。ANSIC標(biāo)準(zhǔn)指定的名字如表13.2所示(見(jiàn)書上P345)。“位移量”指以“起始點(diǎn)”為基點(diǎn),向前移動(dòng)的字節(jié)數(shù)。ANSIC和大多數(shù)C版本要求位移量是long型數(shù)據(jù)。這樣當(dāng)文件的長(zhǎng)度大于64K時(shí)不致出問(wèn)題。ANSIC標(biāo)準(zhǔn)規(guī)定在數(shù)字的末尾加一個(gè)字母L,就表示是long型。下面是fseek函數(shù)調(diào)用的幾個(gè)例子:fseek(fp,100L,0);將位置指針移到離文件頭100個(gè)字節(jié)處fseek(fp,50L,1);將位置指針移到離當(dāng)前位置50個(gè)字節(jié)處fseek(fp,-10L,2);將位置指針從文件末尾處向后退10個(gè)字節(jié)fseek函數(shù)和隨機(jī)讀寫fseek函數(shù)的調(diào)用形式為:fseek示例例12.5在磁盤文件上存有10個(gè)學(xué)生的數(shù)據(jù)。要求將第1、3、5、7、9個(gè)學(xué)生數(shù)據(jù)輸入計(jì)算機(jī),并在屏幕上顯示出來(lái)。源代碼參見(jiàn)12-5.cfseek示例例12.5在磁盤文件上存有10個(gè)學(xué)生的數(shù)據(jù)。ftell函數(shù)ftell函數(shù)的作用是得到流式文件中的當(dāng)前位置,用相對(duì)于文件開頭的位移量來(lái)表示。由于文件中的位置指針經(jīng)常移動(dòng),人們往往不容易知道其當(dāng)前位置。用ftell函數(shù)可以得到當(dāng)前位置。如果ftell函數(shù)返回值為-1L,表示出錯(cuò)。例如: i=ftell(fp); if(i==-1L) { printf("error\n"); }ftell函數(shù)ftell函數(shù)的作用是得到流式文件中的當(dāng)前位置(六)出錯(cuò)的檢測(cè)(六)出錯(cuò)的檢測(cè)ferror函數(shù)在調(diào)用各種輸入輸出函數(shù)(如putc、getc、fread、fwrite等)時(shí),如果出現(xiàn)錯(cuò)誤,除了函數(shù)返回值有所反映外,還可以用ferror函數(shù)檢查。它的一般調(diào)用形式為: ferror(fp);如果ferror返回值為0(假),表示未出錯(cuò)。如果返回一個(gè)非零值,表示出錯(cuò)。應(yīng)該注意,對(duì)同一個(gè)文件每一次調(diào)用輸入輸出函數(shù),均產(chǎn)生一個(gè)新的ferror函數(shù)值,因此,應(yīng)當(dāng)在調(diào)用一個(gè)輸入輸出函數(shù)后立即檢查ferror函數(shù)的值,否則信息會(huì)丟失。在執(zhí)行fopen函數(shù)時(shí),ferror函數(shù)的初始值自動(dòng)置為0。ferror函數(shù)在調(diào)用各種輸入輸出函數(shù)(如putc、getcclearerr函數(shù)它的作用是使文件錯(cuò)誤標(biāo)志和文件結(jié)束標(biāo)志置為0。假設(shè)在調(diào)用一個(gè)輸入輸出函數(shù)時(shí)出現(xiàn)錯(cuò)誤,ferror函數(shù)值為一個(gè)非零值。在調(diào)用clearerr(fp)后,ferror(fp)的值變成0。只要出現(xiàn)錯(cuò)誤標(biāo)志,就一直保留,直到對(duì)同一文件調(diào)用clearerr函數(shù)或rewind函數(shù),或任何其他一個(gè)輸入輸出函數(shù)。clearerr函數(shù)它的作用是使文件錯(cuò)誤標(biāo)志和文件結(jié)束標(biāo)志置(七)文件輸入輸出小結(jié)(七)文件輸入輸出小結(jié)文件使用可以參考表12-3(書P307)和表12-1(書P293);在實(shí)際需要時(shí),可以查閱這兩個(gè)表。當(dāng)然,這兩個(gè)表列出的內(nèi)容只是常用的函數(shù)和標(biāo)志。文件使用可以參考表12-3(書P307)和表12-1(書P2第八章

文件第八章

文件C文件概述文件類型指針文件的打開和關(guān)閉文件的讀寫文件的定位出錯(cuò)的檢測(cè)文件的輸入輸出小結(jié)C文件概述(一)C文件概述(一)C文件概述C文件概述文件(file)是程序設(shè)計(jì)中一個(gè)重要的概念。所謂“文件”一般指存儲(chǔ)在外部介質(zhì)上數(shù)據(jù)的集合。一批數(shù)據(jù)是以文件的形式存放在外部介質(zhì)(如磁盤)上的。操作系統(tǒng)是以文件為單位對(duì)數(shù)據(jù)進(jìn)行管理的,也就是說(shuō),如果想找存在外部介質(zhì)上的數(shù)據(jù),必須先按文件名找到所指定的文件,然后再?gòu)脑撐募凶x取數(shù)據(jù)。要向外部介質(zhì)上存儲(chǔ)數(shù)據(jù)也必須先建立一個(gè)文件(以文件名標(biāo)識(shí)),才能向它輸出數(shù)據(jù)。以前各章中所用到的輸入和輸出,都是以終端為對(duì)象的,即從終端鍵盤輸入數(shù)據(jù),運(yùn)行結(jié)果輸出到終端上。從操作系統(tǒng)的角度看,每一個(gè)與主機(jī)相聯(lián)的輸入輸出設(shè)備都看作是一個(gè)文件。例如,終端鍵盤是輸入文件,顯示屏和打印機(jī)是輸出文件。C文件概述文件(file)是程序設(shè)計(jì)中一個(gè)重要的概念。C文件概述在程序運(yùn)行時(shí),常常需要將一些數(shù)據(jù)(運(yùn)行的最終結(jié)果或中間數(shù)據(jù))輸出到磁盤上存放起來(lái),以后需要時(shí)再?gòu)拇疟P中輸入到計(jì)算機(jī)內(nèi)存。這就要用到磁盤文件。C語(yǔ)言把文件看作是一個(gè)字符(字節(jié))的序列,即由一個(gè)一個(gè)字符(字節(jié))的數(shù)據(jù)順序組成。根據(jù)數(shù)據(jù)的組織形式,可分為ASCII文件和二進(jìn)制文件。ASCII文件又稱文本(text)文件,它的每一個(gè)字節(jié)放一個(gè)ASCII代碼,代表一個(gè)字符。二進(jìn)制文件是把內(nèi)存中的數(shù)據(jù)按其在內(nèi)存中的存儲(chǔ)形式原樣輸出到磁盤上存放。如果有一個(gè)整數(shù)10000,在內(nèi)存中占4個(gè)字節(jié),如果按ASCII碼形式輸出,則占5個(gè)字節(jié),而按二進(jìn)制形式輸出,在磁盤上只占4個(gè)字節(jié)。用ASCII碼形式輸出與字符一一對(duì)應(yīng),一個(gè)字節(jié)代表一個(gè)字符,一個(gè)字節(jié)代表一個(gè)字符,因而便于對(duì)字符進(jìn)行逐個(gè)處理,也便于輸出字符。但一般占存儲(chǔ)空間較多,而且要花費(fèi)轉(zhuǎn)換時(shí)間(二進(jìn)制形式與ASCII碼間的轉(zhuǎn)換)。用二進(jìn)制形式輸出數(shù)值,可以節(jié)省外存空間和轉(zhuǎn)換時(shí)間,但一個(gè)字節(jié)并不對(duì)應(yīng)一個(gè)字符,不能直接輸出字符形式。一般中間結(jié)果數(shù)據(jù)需要暫時(shí)保存在外存上以后又需要輸入到內(nèi)存的,常用二進(jìn)制文件保存。C文件概述在程序運(yùn)行時(shí),常常需要將一些數(shù)據(jù)(運(yùn)行的最終結(jié)果或C文件概述由前所述,一個(gè)C文件是一個(gè)字節(jié)流或二進(jìn)制流。它把數(shù)據(jù)看作是一連串的字符(字節(jié)),而不考慮記錄的界限。換句話說(shuō),C語(yǔ)言中文件并不是由記錄(record)組成的。在C語(yǔ)言中對(duì)文件的存取是以字符(字節(jié))為單位的。輸入輸出的數(shù)據(jù)流的開始和結(jié)束僅受程序控制而不受物理符號(hào)(如回車換行符)控制。也就是說(shuō),在輸出時(shí)不會(huì)自動(dòng)增加回車換行符以作為記錄結(jié)束的標(biāo)志,輸入時(shí)不以回車換行符作為記錄的間隔(事實(shí)上C文件并不由記錄構(gòu)成)。我們把這種文件稱為流式文件。C語(yǔ)言允許對(duì)文件存取一個(gè)字符,這就增加了處理的靈活性。在C語(yǔ)言中,沒(méi)有輸入輸出語(yǔ)句,對(duì)文件的讀寫都是用庫(kù)函數(shù)來(lái)實(shí)現(xiàn)的。ANSI規(guī)定了標(biāo)準(zhǔn)輸入輸出函數(shù),用它們對(duì)文件進(jìn)行讀寫。C文件概述由前所述,一個(gè)C文件是一個(gè)字節(jié)流或二進(jìn)制流。它把數(shù)C文件概述有兩種對(duì)文件的處理方法:一種叫“緩沖文件系統(tǒng)”;一種叫“非緩沖文件系統(tǒng)”。所謂緩沖文件系統(tǒng)是指系統(tǒng)自動(dòng)地在內(nèi)存區(qū)為每一個(gè)正在使用的文件名開辟一個(gè)緩沖區(qū)。從內(nèi)存向磁盤輸出數(shù)據(jù)必須先送到內(nèi)存中的緩沖區(qū),裝滿緩沖區(qū)后才一起送到磁盤去。如果從磁盤向內(nèi)存讀入數(shù)據(jù),則一次從磁盤文件將一批數(shù)據(jù)輸入到內(nèi)存緩沖區(qū)(充滿緩沖區(qū)),然后再?gòu)木彌_區(qū)逐個(gè)地將數(shù)據(jù)送到程序數(shù)據(jù)區(qū)(給程序變量)。如下圖所示。緩沖區(qū)的大小由各個(gè)具體的C版本確定,一般為512字節(jié)。C文件概述有兩種對(duì)文件的處理方法:C語(yǔ)言第9章-文件教學(xué)課件C文件概述所謂“非緩沖文件系統(tǒng)”是指系統(tǒng)不自動(dòng)開辟確定大小的緩沖區(qū),而由程序?yàn)槊總€(gè)文件設(shè)定緩沖區(qū)。在UNIX系統(tǒng)下,用緩沖文件系統(tǒng)來(lái)處理文本文件,用非緩沖文件系統(tǒng)處理二進(jìn)制文件。用緩沖文件系統(tǒng)進(jìn)行的輸入輸出又稱為高級(jí)(或高層)磁盤輸入輸出(高層I/O)。用非緩沖文件系統(tǒng)進(jìn)行的輸入輸出又稱為低級(jí)(低層)輸入輸出系統(tǒng)。ANSIC標(biāo)準(zhǔn)決定不采用非緩沖文件系統(tǒng),而只采用緩沖文件系統(tǒng)。即既用緩沖文件系統(tǒng)處理文本文件,也用它來(lái)處理二進(jìn)制文件。也就是將緩沖文件系統(tǒng)擴(kuò)充為可以處理二進(jìn)制文件。本章只介紹ANSIC規(guī)定的文件系統(tǒng)以及對(duì)它的讀寫。C文件概述所謂“非緩沖文件系統(tǒng)”是指系統(tǒng)不自動(dòng)開辟確定大小的(二)文件類型指針(二)文件類型指針文件類型指針緩沖文件系統(tǒng)中,關(guān)鍵的概念是“文件指針”。每個(gè)被使用的文件都在內(nèi)存中開辟一個(gè)區(qū),用來(lái)存放文件的有關(guān)信息(如文件的名字、文件狀態(tài)及文件當(dāng)前位置等)。這些信息是保存在一個(gè)結(jié)構(gòu)體變量中的。該結(jié)構(gòu)體類型是由系統(tǒng)定義的,取名為FILE。TurboC在stdio.h文件中有以下的文件類型聲明:文件類型指針緩沖文件系統(tǒng)中,關(guān)鍵的概念是“文件指針”。每個(gè)被typedefstruct{ shortlevel;/*緩沖區(qū)“滿”或“空”的程度*/ unsignedflags;/*文件狀態(tài)標(biāo)志*/ charfd;/*文件描述符*/ unsignedcharhold;/*如無(wú)緩沖區(qū)不讀取字符*/ shortbsize;/*緩沖區(qū)的大小*/ unsignedchar*baffer;/*數(shù)據(jù)緩沖區(qū)的位置*/ unsignedar*curp;/*指針,當(dāng)前的指向*/ unsignedistemp;/*臨時(shí)文件,指示器*/ shorttoken;/*用于有效性檢查*/}FILE;typedefstruct文件類型指針可以定義文件型指針變量。如: FILEfp;如果有n個(gè)文件,一般應(yīng)設(shè)n個(gè)指針變量(指向FILE類型結(jié)構(gòu)體的指針變量),使它們分別指向n個(gè)文件(確切地說(shuō)指向存放該文件信息的結(jié)構(gòu)體變量),以實(shí)現(xiàn)對(duì)文件的訪問(wèn)。文件類型指針可以定義文件型指針變量。如:(三)文件的打開與關(guān)閉(三)文件的打開與關(guān)閉文件打開fopen函數(shù)對(duì)文件讀寫之前應(yīng)該“打開”該文件,在使用結(jié)束之后應(yīng)關(guān)閉該文件。ANSIC規(guī)定了標(biāo)準(zhǔn)輸入輸出函數(shù)庫(kù),用fopen()函數(shù)來(lái)實(shí)現(xiàn)打開文件。fopen函數(shù)的調(diào)用方式通常為 FILE*fp; fp=fopen(文件名,使用文件方式);例如: fp=fopen("a1","r");可以看出,在打開一個(gè)文件時(shí),通知給編譯系統(tǒng)以下3個(gè)信息:

①需要打開的文件名,也就是準(zhǔn)備訪問(wèn)的文件的名字。②使用文件的方式(“讀”還是“寫”等)。③讓哪一個(gè)指針變量指向被打開的文件。文件打開fopen函數(shù)對(duì)文件讀寫之前應(yīng)該“打開”該文件,在使文件打開fopen函數(shù)文件使用方式參見(jiàn)書上P333表13-1。說(shuō)明:1)用“r”方式:只讀方式,打開的文件只能用于向計(jì)算機(jī)輸入而不能用作向該文件輸出數(shù)據(jù),而且該文件應(yīng)該已經(jīng)存在,不能用“r”方式打開一個(gè)并不存在的文件(即輸入文件),否則出錯(cuò)。2)用“w”方式:只寫方式,打開的文件只能用于向該文件寫數(shù)據(jù)(即輸出文件),而不能用來(lái)向計(jì)算機(jī)輸入。如果原來(lái)不存在該文件,則在打開時(shí)新建立一個(gè)以指定的名字命名的文件。如果原來(lái)已存在一個(gè)以該文件名命名的文件,則在打開時(shí)將該文件刪去,然后重新建立一個(gè)新文件。文件打開fopen函數(shù)文件使用方式參見(jiàn)書上P333表13-1文件打開fopen函數(shù)3)如果希望向文件末尾添加新的數(shù)據(jù)(不希望刪除原有數(shù)據(jù)),則應(yīng)該用“a”方式打開。但此時(shí)該文件必須已存在,否則將得到出錯(cuò)信息。打開時(shí),位置指針移到文件末尾。4)用“r+”、“w+”、“a+”方式打開的文件既可以用來(lái)輸入數(shù)據(jù),也可以用來(lái)輸出數(shù)據(jù)。用“r+”方式時(shí)該文件應(yīng)該已經(jīng)存在,以便能向計(jì)算機(jī)輸入數(shù)據(jù)。用“w+”方式則新建立一個(gè)文件,先向此文件寫數(shù)據(jù),然后可以讀此文件中的數(shù)據(jù)。用“a+”方式打開的文件,原來(lái)的文件不被刪去,位置指針移到文件末尾,可以添加,也可以讀。文件打開fopen函數(shù)3)如果希望向文件末尾添加新的數(shù)據(jù)(不文件打開fopen函數(shù)5)如果不能實(shí)現(xiàn)“打開”的任務(wù),fopen函數(shù)將會(huì)帶回一個(gè)出錯(cuò)信息。出錯(cuò)的原因可能是用“r”方式打開一個(gè)并不存在的文件;磁盤出故障;磁盤已滿無(wú)法建立新文件等。此時(shí)fopen函數(shù)將帶回一個(gè)空指針值NULL(NULL在stdio.h文件中已被定義為0)。常用下面的方法打開一個(gè)文件: if((fp=fopen("file1","r"))==NULL) { printf("cannotopenthisfile\n"); …… }即先檢查打開的操作有否出錯(cuò),如果有錯(cuò)就在終端上輸出“cannotopenthisfile”。文件打開fopen函數(shù)5)如果不能實(shí)現(xiàn)“打開”的任務(wù),fop文件打開fopen函數(shù)6)用以上方式可以打開文本文件或二進(jìn)制文件,這是ANSIC的規(guī)定,用同一種緩沖文件系統(tǒng)來(lái)處理文本文件和二進(jìn)制文件。但目前使用的有些C編譯系統(tǒng)可能不完全提供所有這些功能(例如有的只能用“r”、“w”、“a”方式),有的C版本不用“r+”、“w+”、“a+”,而用“rw”、“wr”、“ar”等,請(qǐng)讀者注意所用系統(tǒng)的規(guī)定。(7)在向計(jì)算機(jī)輸入文本文件時(shí),將回車換行符轉(zhuǎn)換為一個(gè)換行符,在輸出時(shí)把換行符轉(zhuǎn)換成為回車和換行兩個(gè)字符。在用二進(jìn)制文件時(shí),不進(jìn)行這種轉(zhuǎn)換,在內(nèi)存中的數(shù)據(jù)形式與輸出到外部文件中的數(shù)據(jù)形式完全一致,一一對(duì)應(yīng)。文件打開fopen函數(shù)6)用以上方式可以打開文本文件或二進(jìn)制文件打開fopen函數(shù)8)在程序開始運(yùn)行時(shí),系統(tǒng)自動(dòng)打開3個(gè)標(biāo)準(zhǔn)文件:標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出、標(biāo)準(zhǔn)出錯(cuò)輸出。通常這3個(gè)文件都與終端相聯(lián)系。因此以前我們所用到的從終端輸入或輸出都不需要打開終端文件。系統(tǒng)自動(dòng)定義了3個(gè)文件指針stdin、stdout和stderr,分別指向終端輸入、終端輸出和標(biāo)準(zhǔn)出錯(cuò)輸?也從終端輸出)。如果程序中指定要從stdin所指的文件輸入數(shù)據(jù),就是指從終端鍵盤輸入數(shù)據(jù)。文件打開fopen函數(shù)8)在程序開始運(yùn)行時(shí),系統(tǒng)自動(dòng)打開3個(gè)文件關(guān)閉fclose函數(shù)在使用完一個(gè)文件后應(yīng)該關(guān)閉它,以防止它再被誤用。“關(guān)閉”就是使文件指針變量不指向該文件,也就是文件指針變量與文件“脫鉤”,此后不能再通過(guò)該指針對(duì)原來(lái)與其相聯(lián)系的文件進(jìn)行讀寫操作。除非再次打開,使該指針變量重新指向該文件。用fclose函數(shù)關(guān)閉文件。fclose函數(shù)調(diào)用的一般形式為 fclose(文件指針);例如: fclose(fp);fclose函數(shù)也帶回一個(gè)值,當(dāng)順利地執(zhí)行了關(guān)閉操作,則返回值為0;否則返回EOF(-1)。文件關(guān)閉fclose函數(shù)在使用完一個(gè)文件后應(yīng)該關(guān)閉它,以防止文件關(guān)閉fclose函數(shù)應(yīng)該養(yǎng)成在程序終止之前關(guān)閉所有文件的習(xí)慣,如果不關(guān)閉文件將會(huì)丟失數(shù)據(jù)。因?yàn)?,如前所述,在向文件寫?shù)據(jù)時(shí),是先將數(shù)據(jù)輸?shù)骄彌_區(qū),待緩沖區(qū)充滿后才正式輸出給文件。如果當(dāng)數(shù)據(jù)未充滿緩沖區(qū)而程序結(jié)束運(yùn)行,就會(huì)將緩沖區(qū)中的數(shù)據(jù)丟失。用fclose函數(shù)關(guān)閉文件,可以避免這個(gè)問(wèn)題,它先把緩沖區(qū)中的數(shù)據(jù)輸出到磁盤文件,然后才釋放文件指針變量。文件關(guān)閉fclose函數(shù)應(yīng)該養(yǎng)成在程序終止之前關(guān)閉所有文件的(四)文件的讀寫(四)文件的讀寫fputc寫文件函數(shù)把一個(gè)字符寫到磁盤文件上去。其一般調(diào)用形式為: fputc(ch,fp);其中:ch是要輸出的字符,它可以是一個(gè)字符常量,也可以是一個(gè)字符變量。fp是文件指針變量。fputc(ch,fp)函數(shù)的作用是將字符(ch的值)輸出到fp所指向的文件中去。fputc函數(shù)也帶回一個(gè)值:如果輸出成功則返回值就是輸出的字符;如果輸出失敗,則返回一個(gè)EOF(-1)。EOF是在stdio.h文件中定義的符號(hào)常量,值為-1。fputc寫文件函數(shù)把一個(gè)字符寫到磁盤文件上去。其一般調(diào)用形fputc寫文件函數(shù)在前面介紹過(guò)putchar函數(shù),其實(shí)putchar是從fputc函數(shù)派生出來(lái)的。putchar(c)是在stdio.h文件中用預(yù)處理命令#define定義的宏:#defineputchar(c)fputc(c,stdout)前面已敘述,stdout是系統(tǒng)定義的文件指針變量,它與終端輸出相連。fputc(c,stdout)的作用是將c的值輸出到終端。用宏putchar(c)比寫fputc(c,stdout)簡(jiǎn)單一些。從用戶的角度,可以把putchar(c)看作函數(shù)而不必嚴(yán)格地稱它為宏。fputc寫文件函數(shù)在前面介紹過(guò)putchar函數(shù),其實(shí)pufgetc讀文件函數(shù)從指定的文件讀入一個(gè)字符,該文件必須是以讀或讀寫方式打開的。fgetc函數(shù)的調(diào)用形式為 ch=fgetc(fp);fp為文件型指針變量,ch為字符變量。fgetc函數(shù)帶回一個(gè)字符,賦給ch。如果在執(zhí)行fgetc函數(shù)讀字符時(shí)遇到文件結(jié)束符,函數(shù)返回一個(gè)文件結(jié)束標(biāo)志EOF(-1)。如果想從一個(gè)磁盤文件順序讀入字符并在屏幕上顯示出來(lái),可以: ch=fgetc(fp); while(ch!=EOF) { putchar(ch); ch=fgetc(fp);}fgetc讀文件函數(shù)從指定的文件讀入一個(gè)字符,該文件必須是以feof()判斷文件是否結(jié)束函數(shù)注意:EOF不是可輸出字符,因此不能在屏幕上顯示。由于字符的ASCII碼不可能出現(xiàn)-1,因此EOF定義為-1是合適的。當(dāng)讀入的字符值等于-1(即EOF)時(shí),表示讀入的已不是正常的字符而是文件結(jié)束符。但以上只適用于讀文本文件的情況?,F(xiàn)在ANSIC已允許用緩沖文件系統(tǒng)處理二進(jìn)制文件,而讀入某一個(gè)字節(jié)中的二進(jìn)制數(shù)據(jù)的值有可能是-1,而這又恰好是EOF的值。這就出現(xiàn)了需要讀入有用數(shù)據(jù)而卻被處理為“文件結(jié)束”的情況。為了解決這個(gè)問(wèn)題,ANSIC提供一個(gè)feof函數(shù)來(lái)判斷文件是否真的結(jié)束。 feof(fp)用來(lái)測(cè)試fp所指向的文件當(dāng)前狀態(tài)是否“文件結(jié)束”。如果是文件結(jié)束,函數(shù)feof(fp)的值為1(真),否則為0(假)。feof()判斷文件是否結(jié)束函數(shù)注意:EOF不是可輸出字符,feof()判斷文件是否結(jié)束函數(shù)如: while(!feof(fp)) { c=fgetc(fp); …}feof()判斷文件是否結(jié)束函數(shù)如:fputc和fgetc舉例例12.1從鍵盤輸入一些字符,逐個(gè)把它們送到磁盤上去,直到輸入一個(gè)“#”為止。源碼參見(jiàn)12-1.c例12.2將一個(gè)磁盤文件中的信息復(fù)制到另一個(gè)磁盤文件中。源碼參見(jiàn)12-2\a.c使用命令行方式輸入兩個(gè)文件名;源碼參見(jiàn)12-2\b.cfputc和fgetc舉例例12.1從鍵盤輸入一些字符,逐fread和fwrite函數(shù)ANSIC標(biāo)準(zhǔn)提出設(shè)置兩個(gè)函數(shù)(fread和fwrite),用來(lái)讀寫一個(gè)數(shù)據(jù)塊。它們的一般調(diào)用形式為 fread(buffer,size,count,fp); fwrite(buffer,size,count,fp);其中:buffer:是一個(gè)指針。對(duì)fread來(lái)說(shuō),它是讀入數(shù)據(jù)的存放地址。對(duì)fwrite來(lái)說(shuō),是要輸出數(shù)據(jù)的地址(以上指的是起始地址)。size:要讀寫的字節(jié)數(shù)。count:要進(jìn)行讀寫多少個(gè)size字節(jié)的數(shù)據(jù)項(xiàng)。fp:文件型指針。如果fread或fwrite調(diào)用成功,則函數(shù)返回值為count的值,即輸入或輸出數(shù)據(jù)項(xiàng)的完整個(gè)數(shù)。fread和fwrite函數(shù)ANSIC標(biāo)準(zhǔn)提出設(shè)置兩個(gè)函數(shù)fread和fwrite函數(shù)如果文件以二進(jìn)制形式打開,用fread和fwrite函數(shù)就可以讀寫任何類型的信息,如: fread(f,4,2,fp);其中f是一個(gè)實(shí)型數(shù)組名。一個(gè)實(shí)型變量占4個(gè)字節(jié)。這個(gè)函數(shù)從fp所指向的文件讀入2次(每次4個(gè)字節(jié))數(shù)據(jù),存儲(chǔ)到數(shù)組f中。fread和fwrite函數(shù)如果文件以二進(jìn)制形式打開,用frfread和fwrite函數(shù)如果有一個(gè)如下的結(jié)構(gòu)體類型: structstudent-type { charname[10]; intnum; intage; charaddr[30]; }stud[40];假設(shè)學(xué)生的數(shù)據(jù)已存放在磁盤文件中,可以用下面的for語(yǔ)句和fread函數(shù)讀入40個(gè)學(xué)生的數(shù)據(jù): for(i=0;i<40;i++) { fread(&stud[i],sizeof(structstudent-type),1,fp); }同樣,以下for語(yǔ)句和fwrite函數(shù)可以將內(nèi)存中的學(xué)生數(shù)據(jù)輸出到磁盤文件中去: for(i=0;i<40,i++) { fwrite(&stud[i],sizeof(structstudent-type),1,fp); }fread和fwrite函數(shù)如果有一個(gè)如下的結(jié)構(gòu)體類型:fread和fwrite函數(shù)舉例例12.3從鍵盤輸入4個(gè)學(xué)生的有關(guān)數(shù)據(jù),然后把它們轉(zhuǎn)存到磁盤文件上去。源碼參見(jiàn)12-3fread和fwrite函數(shù)舉例例12.3從鍵盤輸入4個(gè)學(xué)其它讀寫函數(shù)自學(xué)。其它讀寫函數(shù)自學(xué)。(五)文件的定位(五)文件的定位文件中有一個(gè)位置指針,指向當(dāng)前讀寫的位置。如果順序讀

溫馨提示

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

評(píng)論

0/150

提交評(píng)論