版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第十章文件10.1文件
10.2緩沖文件系統(tǒng)基礎10.1文件10.1.1文件的概念
磁盤文件在DOS管理中被定義為存貯在外部介質上的程序或數(shù)據(jù)的集合,是一批邏輯上有聯(lián)系的數(shù)據(jù)每個文件都有一個文件名作為標識,每個文件在磁盤中的具體存放位置、格式都由操作系統(tǒng)中的文件系統(tǒng)管理,也就是說,操作系統(tǒng)是以文件為單位對程序或數(shù)據(jù)進行管理的。編輯后存于磁盤上的源程序文件*.C,經編譯后得到的目標文件*.OBJ,連接之后形成的可執(zhí)行文件*.EXE等。
在C語言中文件的含義更為廣泛,不僅包含以上所述的磁盤文件,還包括一切能進行輸入/輸出的終端設備,它們被看成是設備文件。如鍵盤常稱為標準輸入文件,顯示器稱為標準輸出文件。文件是由磁盤文件和設備文件組成的。作為磁盤文件之一的數(shù)據(jù)文件是本章學習的主要對象。數(shù)據(jù)文件可以看作是C中最后一種數(shù)據(jù)類型,是C語言重要的組成部分。根據(jù)文件內數(shù)據(jù)的組織形式,文件可分為文本(text)文件和二進制文件。文本文件又稱為ASCII碼文件,它的每一個字節(jié)存放一個字符的ASCII碼。10.1.2數(shù)據(jù)流
數(shù)據(jù)流是對數(shù)據(jù)輸入輸出行為的一種抽象。各種各樣的終端設備或磁盤文件的細節(jié)是非常復雜多樣的直接對它們編程將會非常繁瑣。引入數(shù)據(jù)流的概念有效地解決了這一難題。只要建立了輸入輸出數(shù)據(jù)流,編程者在應用程序中就不需要關心底層輸入輸出設備或是任何磁盤文件的具體細節(jié)差異。程序中要輸入數(shù)據(jù),只需從輸入數(shù)據(jù)流中讀入;輸出數(shù)據(jù)只需向輸出數(shù)據(jù)流中寫出即可,這樣就使程序完全與具體硬件資源脫離了關系,也就是說數(shù)據(jù)流使C程序與具體系統(tǒng)完全不相關,使C程序可以非常方便地移植。10.1.3C的文件系統(tǒng)及其與流的關系C的文件系統(tǒng)可分為緩沖文件系統(tǒng)和非緩沖文件系統(tǒng)兩類。所謂緩沖文件系統(tǒng),又稱高級磁盤輸入輸出系統(tǒng)。在調用這種文件處理函數(shù)時,會自動在用戶內存區(qū)中為每一個正在使用的文件劃出一片存貯單元,稱為開辟一個緩沖區(qū)。設立緩沖區(qū)的原因是磁盤的讀寫速度比內存的處理速度要慢很多,而且磁盤驅動器是機電設備,定位精度比較差,所以磁盤數(shù)據(jù)存取要以扇區(qū)(磁盤上某磁道中的一個弧形段,通常存放固定數(shù)量的數(shù)據(jù))或者簇(由若干扇區(qū)組成)為單位。10.2緩沖文件系統(tǒng)基礎
一般緩沖文件操作有三個必需的步驟:(1)在使用文件前要調用打開函數(shù)將文件打開,若打開失敗,則返回一個空指針;若打開正常,可以得到一個文件指針,并利用它繼續(xù)對文件操作。
(2)可調用各種有關函數(shù),利用該指針對文件進行具體處理,一般要對文件進行讀或寫操作。
(3)在文件用完時,應及時調用關閉函數(shù)來關閉文件,切斷數(shù)據(jù)流,防止數(shù)據(jù)遺失或誤操作破壞文件內容。10.2.1文件指針
文件類型FILE不是C語言的新類型,它是用typedef定義出來的有關文件信息的一種結構體類型。如TurboC2.0版的stdio.h文件中有如下的定義:typedefstruct{shortlevel;/*緩沖區(qū)“滿”或“空”的程度*/unsignedflags;/*文件狀態(tài)標志*/charfd;/*文件描述符*/unsignedcharhold;/*如無緩沖區(qū)不讀取字符*/shortbsize;/*緩沖區(qū)的大小*/unsignedchar*buffer;/*數(shù)據(jù)緩沖區(qū)的位置*/unsignedchar*curp;/*當前工作指針*/unsignedistemp;/*臨時文件,指示器*/shorttoken;/*用于有效性檢查*/}FILE;10.2.2打開文件(fopen函數(shù))打開函數(shù)fopen()的調用方式是:FILE*fp;fp=fopen(文件名,使用文件方式);例如,fp=fopen("A1.DAT","r");表12.1文件使用方式10.2.3關閉文件(fclose函數(shù))
在使用完一個文件后應該調用fclose函數(shù)關閉文件。
fclose函數(shù)的調用格式為fclose(文件指針)。例如fclose(fp);就把指針fp所指的文件關閉了,也就是斷開了打開文件時建立的數(shù)據(jù)流——fp與具體文件的聯(lián)系,即不能再通過fp對某個具體文件進行操作。
如果在程序終止之前不關閉文件,將可能丟失緩沖區(qū)中最后一批未處理的數(shù)據(jù),因為fclose函數(shù)的調用不僅釋放文件指針,還刷新緩沖區(qū)。fclose函數(shù)將緩沖區(qū)中可能遺留的未裝滿送走的數(shù)據(jù)輸入內存或輸出至磁盤文件,以確保數(shù)據(jù)不丟失。當然,程序結束時會自動關閉文件,但用完文件后及時關閉是一個好的編程習慣。
fclose函數(shù)也返回一個值:0表示順利返回,非0表示關閉錯誤。10.2.4文件的讀寫
1.fputc函數(shù)和fgetc函數(shù)
fputc函數(shù)的調用形式為
fputc(ch,fp);
該函數(shù)的作用是將字符(ch的值)輸出到fp所指向的文件上去。其中ch是要輸出的字符,它可以是一個字符常量,也可以是一個字符變量。fp是文件指針,它是從fopen函數(shù)得到的返回值。fputc函數(shù)也帶回一個值,如果輸出成功則返回值就是輸出的字符;如果輸出失敗,則返回一個EOF。EOF是在stdio.h文件中定義的符號常量,值為-1。fgetc函數(shù)的調用形式為
ch=fgetc(fp);
該函數(shù)的作用是從指定文件讀入一個字符,該文件必須是以讀或讀寫方式打開的。其中fp為文件型指針,指向所打開備讀的文件;ch為字符變量,接收fgetc函數(shù)帶回的字符如果在執(zhí)行fgetc讀字符時遇到文件結束符,函數(shù)則返回一個文件結束標志EOF,可以利用它來判斷是否讀完了文件中的數(shù)據(jù)。如想從一個磁盤文件順序讀入字符并在屏幕上顯示出來,可編程為
while((ch=fgetc(fp))![KG-*4]=EOF)putchar(ch);EOF不是可輸出字符,因此在屏幕上顯示不出來。由于字符的ASCII碼不可能出現(xiàn)-l,因此EOF定義為-l是合適的。當讀入的字符值等于-1(即EOF)時,表示讀入的已不是正常的字符而是文件結束符。但以上只適用于讀文本文件?,F(xiàn)在標準C已允許用緩沖文件系統(tǒng)處理二進制文件,而讀入某一個字節(jié)中的二進制數(shù)據(jù)的值有可能是-1,而這又恰好是EOF的值。這就出現(xiàn)了讀入有用數(shù)據(jù)卻被處理為“文件結束”的情況,即終止符設置不恰當。為了解決這個問題,標準C提供了一個feof()函數(shù)來判斷文件是否真的結束。feof(fp)用來測試fp所指向的文件當前狀態(tài)是否為“文件結束”,如果是文件結束,函數(shù)feof(fp)的值為1(真),否則為0(假)。例如,順序讀入一個二進制文件中的數(shù)據(jù)的程序段如下:
while(!feof(fp)){c=fgetc(fp);
……
}當未遇文件結束時,feof(fp)的值為0,!feof(fp)為l,讀入一個字節(jié)的數(shù)據(jù)賦給變量c(接著可做其它處理),之后再求feof(fp)函數(shù),循環(huán)工作直到文件結束,feof(fp)值變?yōu)?,!feof(fp)值為0,結束while循環(huán)。這種方法也適用于文本文件。
例10.1
建立一個磁盤文件,將鍵入的回車前的若干個字符逐個寫入該文件。#include<stdio.h>main(){FILE*fp;charch,filename[13];printf("\nInputthefile\′sname:");gets(filename);/*注1*/if((fp=fopen(filename,"w"))==NULL){printf("Cannotopenthefile\n");exit(0);}printf("Inputthecharacterstothefile:\n");while((ch=getchar())!=′\n′)/*注2*/{fputc(ch,fp);/*注3*/putchar(ch);/*注4*/}fclose(fp);}運行情況如下:
Inputthefile′sname:fileex1.dat(注1要求的輸入磁盤文件名)
Inputthecharacterstothefile:Whatinsidethefile
(注2要求的鍵入一個字符串)
Whatinsidethefile(注4輸出到顯示器上的字符串,與寫入文件的 內容一樣,以資核對)
程序運行之后,可以查看文件目錄,將多出一個名為fileex1.dat的數(shù)據(jù)文件,可用DOS命令將其內容打印出來:typefileex1.datWhatinsidethefile(由注3行循環(huán)寫入的)
2.fgets函數(shù)和fputs函數(shù)
fgets的作用是從指定文件讀入一個字符串。如:
fgets(str,n,fp);
從fp指向的文件讀入n-1個字符,并把它們放到字符數(shù)組str中,如果在讀入n-1個字符結束之前遇到換行符或EOF,讀入即結束。字符串讀入在最后加一個‘\0’字符,fgets函數(shù)返回值為str的首地址。
fputs函數(shù)的作用是向指定的文件輸出一個字符串,如:
fputs("China",fp);3.fprinf函數(shù)和fscanf函數(shù)
fprintf函數(shù)、fscanf函數(shù)與printf和scanf函數(shù)作用類似,都是格式化讀寫函數(shù)。前二者的讀寫對象是磁盤文件,而后二者是終端設備。所以前二者函數(shù)調用參數(shù)中要多出一代表文件的文件指針。一般調用方式為
fprintf(文件指針,控制字符串,參量表);fscanf(文件指針,控制字符串,參量表);
例10.2
按格式鍵入字符型、整型、實型各一數(shù),寫入文件dform.dat,再讀出送顯。#include<stdio.h>main(){inti,i1;charch,ch1;floatf,f1;FILE*fp;printf("\nInputchif:");scanf("%c%d%f",&ch,&i,&f);if((fp=fopen("dform.dat","w"))==NULL)/*注1*/{printf("Cannotopenthefile\n");exit(0);}fprintf(fp,"%c%5d%4.1f",ch,i,f);/*注2*/fclose(fp);/*注3*/if((fp=fopen("dform.dat","r"))==NULL){printf("Cannotopenthefile\n");exit(0);}fscanf(fp,"%c%d%f",&ch1,&i1,&f1);printf("%c%5d%4.1f",ch1,i1,f1);fclose(fp);}
程序運行情況:
Inputchif:a22.2(提示及輸入)
a22.2(屏幕顯示)
dform.dat中的內容同屏顯。4.fread函數(shù)和fwrite函數(shù)
它們的一般調用形式為
fread(buffer,size,count,fp);fwrite(buffer,size,count,fp);其中:buffer是一個地址。對fread來說,它是讀入數(shù)據(jù)將要存放處的地址。對fwrite來說,是要輸出數(shù)據(jù)的地址(以上指的是起始地址)。
size是要讀寫的一個數(shù)據(jù)塊的字節(jié)數(shù)。
count是要進行讀寫數(shù)據(jù)塊的個數(shù)。
fp是文件指針,指向待讀或寫的文件。例10.3
建立一個有關工人工資的數(shù)據(jù)文件。
#include<stdio.h>
#defineSIZE6structstaff{charname[10];intsalary;intcost;}worker[SIZE];
voidsavef(){FILE*fp;inti;if((fp=fopen("work.dat","wb"))==NULL){printf("Cannotopenthefile\n");return;}for(i=0;i<SIZE;i++)if(fwrite(&worker[i],sizeof(structstaff),1,fp)![KG-*4]=1)printf("Filewriteerror\n");fclose(fp);}main(){inti;printf("\nInput%dworker\′snamesalarycost:\n",SIZE);for(i=0;i<SIZE;i++)
scanf("%s%d%d",worker[i].name,&worker[i].salary,&worker[i].cost);
savef();}10.2.5文件的定位1.rewind函數(shù)
rewind函數(shù)可以強制使當前工作指針指向文件的開頭。一般在要重新從頭讀寫文件時使用。如下例,在讀了文件dfr.dat一遍送顯示器后,文件的位置指針已移到文件的最后,為了重新讀一遍再寫到文件dfw.dat中,必須先執(zhí)行一次rewind函數(shù),才能正確讀出。
例10.4
將已建好的文件dfr.dat的內容順序讀一遍送顯示器,再讀一遍復制到文件dfw.dat中。#include<stdio.h>main(){inti;charch;floatf,f1;FILE*fp1,*fp2;if((fp1=fopen("dfr.dat","r"))==NULL){printf("Cannotopenthefileforreading\n");exit(0);
}if((fp2=fopen("dfw.dat","w"))==NULL){printf("Cannotopenthefileforwriting\n");exit(0);
}fscanf(fp1,"%c%d%f",&ch,&i,&f);printf("%c,%5d,%4.1f\n",ch,i,f);rewind(fp1);fscanf(fp1,"%c%d%f",&ch,&i,&f1);fprintf(fp2,"%c%d%f",ch,i,f1);fclose(fp1);fclose(fp2);}2.fseek函數(shù)
利用fseek函數(shù)可以控制文件位置的指針進行隨機讀寫。
fseek函數(shù)的調用形式為fseek(文件類型指針,位移量,起始點);起始點用0、1或2代表,0——文件的開始,1——當前位置,2——文件末尾;位移量指從起始點向前移動的字節(jié)數(shù);
fseek函數(shù)一般用于二進制文件,因為文本文件要發(fā)生字符轉換,計算位置時容易發(fā)生混亂。
例10.5
將例10.3形成的職工數(shù)據(jù)文件中的第1,3,5個工人的信息讀出、送顯。#include<stdio.h>#defineSIZE6structstaff{c
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度智慧城市建設擔保協(xié)議3篇
- 運動隊訓練中的科技裝備與智能化管理
- 2025版商業(yè)綜合體物業(yè)商鋪裝修管理及維護服務協(xié)議書3篇
- 網(wǎng)絡信息搜索與評價能力的培養(yǎng)方案設計
- 小學數(shù)學課堂的科學實驗教學探討
- 2025年粵教新版選修6歷史下冊階段測試試卷含答案
- 二零二五年度離婚協(xié)議中夫妻共同財產分割及子女撫養(yǎng)協(xié)議范本6篇
- 2025年蘇人新版必修1歷史下冊月考試卷含答案
- 2025版無息醫(yī)療健康貸款合同書示例3篇
- 2025年浙教版選擇性必修三語文下冊階段測試試卷
- 2024年09月2024興業(yè)銀行總行崗測評筆試歷年參考題庫附帶答案詳解
- 山東省煙臺市招遠市2024-2025學年九年級上學期期末考試英語(筆試)試題(含答案)
- 駱駝祥子讀書筆記一至二十四章
- 2025年方大萍安鋼鐵招聘筆試參考題庫含答案解析
- 2024年醫(yī)師定期考核臨床類考試題庫及答案(共500題)
- 2025年電力工程施工企業(yè)發(fā)展戰(zhàn)略和經營計劃
- 2022年公務員多省聯(lián)考《申論》真題(安徽C卷)及答案解析
- 大型活動保安培訓
- 2024年大學本科課程教育心理學教案(全冊完整版)
- 信息系統(tǒng)運維服務類合同6篇
- 江蘇省七市2025屆高三最后一卷物理試卷含解析
評論
0/150
提交評論