精通C程序設(shè)計十一文件操作_第1頁
精通C程序設(shè)計十一文件操作_第2頁
精通C程序設(shè)計十一文件操作_第3頁
精通C程序設(shè)計十一文件操作_第4頁
精通C程序設(shè)計十一文件操作_第5頁
已閱讀5頁,還剩43頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第十一章文件操作本章內(nèi)容提要:11.1C語言文件操作的基本概念11.2C語言文件操作數(shù)據(jù)結(jié)構(gòu)11.3C語言文件操作函數(shù)11.4字符文件應(yīng)用11.5二進(jìn)制文件應(yīng)用重點小結(jié)作業(yè)11.1C語言文件操作的基本概念11.1.1C語言流文件的概念所謂流(stream)是指C語言文件操作函數(shù)與物理文件之間的一種數(shù)據(jù)結(jié)構(gòu)與操作規(guī)程。一般說來,流是指文件按存儲順序形成的字節(jié)序列。

1.緩沖文件內(nèi)存中開辟一個適當(dāng)大小的內(nèi)存塊稱為文件緩沖區(qū),用來保存文件一部分?jǐn)?shù)據(jù),讀寫文件不直接針對物理文件本身,而是對緩沖區(qū)進(jìn)行,由內(nèi)部程序?qū)崿F(xiàn)緩沖區(qū)與文件的數(shù)據(jù)更新。11.1C語言文件操作的基本概念(續(xù)1)2.非緩沖文件任何讀寫操作直接針對物理文件進(jìn)行。緩沖文件可有效減低磁盤的訪問頻度。C語言兩種文件操作方式都提供,但我們主要應(yīng)用的是緩沖文件(即流文件)。ANSIC標(biāo)準(zhǔn)決定不采用非緩沖文件系統(tǒng)而只采用緩沖文件系統(tǒng),因此本章將只介紹C語言的緩沖文件操作函數(shù)。通常所說的流文件就是指ANSI標(biāo)準(zhǔn)的字節(jié)流緩沖文件。11.1C語言文件操作的基本概念(續(xù)2)11.1C語言文件操作的基本概念(續(xù)3完)11.1.2順序文件與隨機文件操作1.順序文件讀文件或者寫文件操作只能按照順序進(jìn)行。對于字節(jié)流文件,即讀/寫文件的第i個字節(jié)前必須順序讀出/寫入前面的i-1個字節(jié)。2.隨機文件對于字節(jié)流文件允許直接讀/寫文件的第i個字節(jié)。

C語言的文件操作函數(shù)兩種方式都可以實現(xiàn)。11.2C語言文件操作數(shù)據(jù)結(jié)構(gòu)1.FILE結(jié)構(gòu)類型定義于stdio.h中,是文件操作的句柄結(jié)構(gòu),我們無需關(guān)心該結(jié)構(gòu)的詳細(xì)內(nèi)容,C函數(shù)通過一個FILE*型指針,對文件進(jìn)行操作。例如:FILE*fp,*fr,*fw;2.空文件指針常量:NULL

等價于03.文件讀操作結(jié)束(失敗)標(biāo)志常量:EOF

等價于-1以上兩個常量均已定義于stdio.h中。11.2C語言文件操作數(shù)據(jù)結(jié)構(gòu)(續(xù)1完)4.系統(tǒng)標(biāo)準(zhǔn)輸入/輸出文件已定義于stdio.h中,用戶可在程序中直接使用。(1)

stdin:標(biāo)準(zhǔn)輸入文件,即鍵盤輸入("r"型)(2)

stdout:標(biāo)準(zhǔn)輸出文件,即顯示屏("w"型)(3)

stderr:標(biāo)準(zhǔn)錯誤輸出文件,一般指顯示屏("w"型)11.3C語言文件操作函數(shù)1.打開文件函數(shù)原形FILE*fopen(char*fname,char*mode);(1)

fname:指文件名,可包含盤符與路徑信息如:"ABC.TXT""C:\\user\\abc.txt"(2)

返回值為NULL表明文件打開失??;否則打開成功,為一個有效的FILE*型指針值。(3)mode:文件打開方式字符串11.3C語言文件操作函數(shù)(續(xù)1)打開方式串操作特點字符文件二進(jìn)制文件"r"或"rt""rb"只讀方式,要求文件必須已經(jīng)存在"w"或"wt""wb"只寫方式,文件存在,則截取文件長度為0,即刪除文件原有數(shù)據(jù),重建文件;文件不存在則建立新的文件"a"或"at""ab"添加寫方式,文件存在,則只能從文件結(jié)尾開始寫入數(shù)據(jù);文件不存在,則新建"r+"或"rt+""rb+"讀寫方式,要求文件必須已經(jīng)存在,可以進(jìn)行全文讀、改寫、添加寫。"wb+"寫讀方式,文件存在,則截取文件長度為0,文件不存在,則建新文件,允許讀出寫入的數(shù)據(jù)和改寫已經(jīng)寫入的數(shù)據(jù)。"a+"或"at+""ab+"添加可讀方式,文件存在,只能添加寫,文件不存在,則建立新文件;允許讀出添加寫入的數(shù)據(jù)和改寫添加寫入的數(shù)據(jù)。"w+"或"wt+"11.3C語言文件操作函數(shù)(續(xù)2)說明:

(a)

打開文件失敗的可能情況主要有:I對于含字母r的打開方式,失敗情況主要是:

文件不存在;文件名或路徑名有錯誤

對含r方式打開的文件,一定要測試文件是否打開成功,否則會帶著錯誤正常運行下去II

對于含有w或a字母的打開方式,失敗的情況主要是:

磁盤空間不足或磁盤故障(b)打開方式串中的字母必須小寫,不能夠大寫。11.3C語言文件操作函數(shù)(續(xù)3)例如:FILE*fr,*fw;fr=fopen("abc.txt","r");if(fr==NULL){printf("Fileopenerror.\n");

exit(0);}fw=fopen("abc.bak","w");2.關(guān)閉文件:(1)intfclose(FILE*fp);/*一般不用返回值*/11.3C語言文件操作函數(shù)(續(xù)4)如:fclose(fr);fclose(fw);對于寫入方式打開的文件,一定要用fclose關(guān)閉文件,否則可能有數(shù)據(jù)未從緩沖區(qū)寫入磁盤。原則上,fclose與fopen配對使用。(2)intfcloseall();該函數(shù)關(guān)閉本應(yīng)用程序所有打開的文件。3.文件讀寫函數(shù)(1)單字節(jié)讀寫函數(shù)(字符與二進(jìn)制文件都適用)11.3C語言文件操作函數(shù)(續(xù)5)intfputc(intch,FILE*fp);ch的低8位(1字節(jié))寫入文件。

成功:返回寫入的該字節(jié)(0~255);

失敗:返回EOF(-1)intfgetc(FILE*fp);從文件中讀出一個字節(jié)并返回。

成功:函數(shù)返回值為0~255,即讀出的字節(jié);

失敗:返回值為EOF(-1)。

11.3C語言文件操作函數(shù)(續(xù)6)(2)字符串讀寫函數(shù)(字符與二進(jìn)制文件均適用)char

fgets(char

s,intn,FILE

fp);從文件中連續(xù)讀出n

1個字符存入字符指針s開始的內(nèi)存,最后自動加上一個字符'\0'。

成功:函數(shù)返回值為s;失敗:返回值為NULL。intfputs(char

s,FILE

fp);將字符串s寫入文件(不寫入'\0')。

成功:函數(shù)返回非負(fù)整數(shù);失敗:返回EOF。11.3C語言文件操作函數(shù)(續(xù)7)(3)格式化讀寫函數(shù)(僅字符文件適用)intfscanf(FILEfp,charformat[,&argument]...);intfprintf(FILEfp,charformat[,expression]...);與scanf與printf的用法完全一樣,但是從字符文件讀寫數(shù)據(jù)。fscanf(stdin,...);

scanf(...);fprintf(stdout,...);

printf(...);11.3C語言文件操作函數(shù)(續(xù)8)(4)

字節(jié)塊讀寫函數(shù)(僅二進(jìn)制文件適用)unsignedfread(void

buffer,unsignedsize,unsignedcount,FILE

fp);從文件中連續(xù)讀出size

count個字節(jié)存入指針buffer開始的內(nèi)存。返回實際讀出的字節(jié)數(shù)。

unsignedfwrite(void

buffer,unsignedsize,unsignedcount,FILE

fp);

從內(nèi)存地址buffer開始,寫size

count字節(jié)到文件中。返回實際寫入文件的字節(jié)數(shù)。

11.3C語言文件操作函數(shù)(續(xù)9)4.數(shù)據(jù)讀寫位置指針操作函數(shù)(1)文件數(shù)據(jù)讀寫位置指針的概念字節(jié)流文件的讀寫位置以字節(jié)為單位編號。長度為n字節(jié)的文件,第一字節(jié)的編號為0,最后一個字節(jié)的編號為n-1,因此文件數(shù)據(jù)讀寫位置指針的有效范圍為0~n-1。(2)數(shù)據(jù)讀寫位置指針的自動移動規(guī)則

(a)

任何方式打開文件時,指針初態(tài)都是0;11.3C語言文件操作函數(shù)(續(xù)10)(b)

含a的打開方式,只要進(jìn)行寫操作,則指針自動移到文件當(dāng)前結(jié)束位置即位置n(n為當(dāng)前文件已有字節(jié)數(shù))處。(c)

進(jìn)行任何讀寫操作時,指針總是從當(dāng)前位置開始讀寫,讀寫結(jié)束后,指針當(dāng)前位置自動移動到讀寫之后的位置。(3)數(shù)據(jù)讀寫位置指針的操作函數(shù)voidrewind(FILE

fp);

重置當(dāng)前讀寫位置指針為0。11.3C語言文件操作函數(shù)(續(xù)11)longftell(FILE*fp);

返回當(dāng)前文件讀寫位置指針值。intfseek(FILE*fp,longoffset,intstartpos);讀寫位置指針移動到偏移startpos指定的位置offset字節(jié)處。startpos=0

SEEK_SET

文件開始處(位置0)

1

SEEK_CUR

當(dāng)前指針位置處

2

SEEK_END

文件結(jié)尾處(位置n)

n為文件當(dāng)前字節(jié)長度11.3C語言文件操作函數(shù)(續(xù)12)SEEK_SETSEEK_CURSEEK_END11.3C語言文件操作函數(shù)(續(xù)13)5.讀操作失敗標(biāo)志函數(shù)intfeof(FILE

fp);當(dāng)且僅當(dāng)文件當(dāng)前讀寫位置指針在有效數(shù)據(jù)區(qū)以外并進(jìn)行了讀操作,函數(shù)返回值不等于0,其余情況,函數(shù)的返回值是0。注意:執(zhí)行fseek、rewind或者任何寫操作后,該函數(shù)的返回值將是0。6.可讀/可寫打開方式中的讀寫操作切換11.3C語言文件操作函數(shù)(續(xù)14)

fopen函數(shù)中的打開方式串若含有+號,允許對文件進(jìn)行讀操作和寫操作。C語言規(guī)定,讀操作和寫操作切換時,中間必須間隔fseek函數(shù)。例如:字節(jié)流為ABCDEFGH…/*以"r+"方式打開文件*/

當(dāng)前讀寫位置指針執(zhí)行語句charch=fgetc(fp);/*ch得到'E'*/ABCDEFGH…/*讀寫位置指針指向F*/當(dāng)前讀寫位置指針11.3C語言文件操作函數(shù)(續(xù)15)此時若將F改寫為f,則

fseek(fp,0L,SEEK_CUR);/

指針原地踏步

/

fputc('f',fp);

/*若不執(zhí)行前面的fseek,此句無法正常寫入*/

ABCDEfGH…/*讀寫位置指針指向G*/當(dāng)前讀寫位置指針11.3C語言文件操作函數(shù)(續(xù)16)7.字符文件與二進(jìn)制文件操作的區(qū)別

若文件以字符文件方式打開時,當(dāng)向文件寫入字節(jié)'\n'(10),寫操作函數(shù)(fputc,fputs,fprintf)先自動寫入字符'\r'(13);

當(dāng)從文件讀到字節(jié)'\r'(13)時,讀操作函數(shù)(fgetc,fgets,fscanf)不返回'\r'而是跳過'\r'讀出緊跟在它后面的字節(jié)'\n'(10),并返回'\n'。

二進(jìn)制文件打開方式?jīng)]有上述特性,即每個字節(jié)都一視同仁。字符文件的內(nèi)容結(jié)構(gòu)請參見教材P23例1.12。11.3C語言文件操作函數(shù)(續(xù)17)8.操作系統(tǒng)文件操作命令函數(shù)頭文件stdio.h文件更名

int

rename(char

oldname,char

newname);成功,函數(shù)返回0,否則返回

1。文件更名必須符合操作系統(tǒng)關(guān)于文件更名的規(guī)定。例如:rename("A1.DAT","A2.DAT");11.3C語言文件操作函數(shù)(續(xù)18完)(2)刪除文件intremove(char

path);刪除磁盤上由文件名path指定的文件。刪除文件成功,返回0,否則返回

1。刪除文件失敗的可能情況是:沒有指定正確的文件名;文件不存在;或者文件是只讀屬性。

例如:remove("D:\\TC\\A.C");11.4字符文件應(yīng)用例11.3打印如下圖形到屏幕上與正文文件ABC.TXT中,要求打印行數(shù)n由鍵盤輸入。135791113151719n行算法設(shè)計:屏幕上怎樣輸出,就在字符文件中怎樣輸出。

#include"stdio.h"voidmain(){intn,i,j,k;FILE

fw;printf("Inputn=");scanf("%d",&n);fw=fopen("abc.txt","w");k=1;for(i=1;i<=n;i++){printf("%s",4

(n

i),"");fprintf(fw,"%

s",4

(n

i),"");for(j=1;j<=i;j){printf("%4d",k);fprintf(fw,"%4d",k);k+=2;}printf("\n");fprintf(fw,"\n");}fclose(fw);}11.4字符文件應(yīng)用(續(xù)1)11.4字符文件應(yīng)用(續(xù)2)例11.4

用正文文件A1.TXT提供數(shù)據(jù)建立一個矩陣,然后輸出轉(zhuǎn)置矩陣到正文文件A2.TXT。算法設(shè)計:設(shè)矩陣為4行3列整型矩陣,建立A1.TXT文件內(nèi)容如下:1235678910111213

文件A1.TXT可用任何字符文件編輯軟件建立,如WINDOWS的"記事本"程序。11.4字符文件應(yīng)用(續(xù)3)#include"stdio.h"#defineN4#defineM3voidmain(){longa[N][M],b[M][N];inti,j;FILE

fw,

fr;fr=fopen("a1.txt","r");fw=fopen("a2.txt","w");if(!fr){printf("Filea1.txtnotfound.\n");return;}for(i=0;i<N;i++)for(j=0;j<M;j++){fscanf(fr,"%ld",&a[i][j]);b[j][i]=a[i][j];}for(i=0;i<M;i++){for(j=0;j<N;j++)fprintf(fw,"%6ld",b[i][j]);fprintf(fw,"\n");}fcloseall();}11.4字符文件應(yīng)用(續(xù)4)問題與思考:(1)建立字符文件A1.TXT時,A1.TXT應(yīng)該存在什么目錄(文件夾)中?答:A1.TXT應(yīng)該存放在與源程序文件相同的目錄中(2)程序建立的A2.TXT存放在哪里?typea1.txt顯示的文件內(nèi)容(該文件可用TC集成環(huán)境或WINDOWS記事本等編輯器建立)12356789101213例11.5編程統(tǒng)計一個C源程序文件的字符行數(shù)。算法設(shè)計:C源程序文件名由鍵盤輸入;統(tǒng)計文件中包含的'\n'字符數(shù)目。輸出文件a2.txt的內(nèi)容

158112691237101311.4字符文件應(yīng)用(續(xù)5)11.4字符文件應(yīng)用(續(xù)6)#include"stdio.h"voidmain(){FILE

fr;charch;charfname[81];intn=0;printf("InputaCsourcefilename:");gets(fname);fr=fopen(fname,"r");if(!fr){printf("file%snotfound.\n",fname);return;}

while(1)

{

ch=fgetc(fr);if(feof(fr))break;if(ch=='\n')n++;

}printf("numberofrows=%d\n",n);fclose(fr);}11.4字符文件應(yīng)用(續(xù)7)例11.6判斷一個C源程序中的大括號{}是否配對。算法設(shè)計:C源程序文件名由鍵盤輸入;設(shè)置一個計數(shù)變量c,初值為0,讀到左{則c自加1,遇到右}則自減1。掃描文件過程中,出現(xiàn)c<0或者掃描結(jié)束后,c>0都說明{}沒有配對。

#include"stdio.h"voidmain(){FILE

fr;intch;charfname[81];intc;printf("InputCsourcefilename:");gets(fname);fr=fopen(fname,"r");if(!fr){printf("file%snotfound.\n",fname);return;}11.4字符文件應(yīng)用(續(xù)8)c=0;

while(1)

{ch=fgetc(fr);if(ch==EOF)break;if(ch

'{')c++;if(ch=='}')c

;if(c<0)break;/

c<0,說明大括號配對不正確

/

}

if(c!=0)printf("braceserror.\n");elseprintf("bracesright.\n");fclose(fr);}11.4字符文件應(yīng)用(續(xù)9)例11.7刪除一個C源程序文件中的注釋。算法設(shè)計:用空格擦寫/*....*/部分。設(shè)兩個長整型變量pos1,pos2,表示注釋開始和結(jié)束的位置。注意查找注釋開始與結(jié)束的方法。ABCD…/*XXXX*/ch1ch2ch1ch2pos1pos2注意:ch1,ch2每循環(huán)一次只推進(jìn)一個字節(jié),才能保證搜索的完整性,如上圖所示。11.4字符文件應(yīng)用(續(xù)10)#include"stdio.h"voidmain(intargc,char

argv[])/*參見教材P2409.4*/{FILE

fp;charfname[81],ch1,ch2;longpos1,pos2;if(argc==2)/

若含有一個文件名參數(shù)

/

fp=fopen(argv[1],"rb+");else{printf("InputaCsourcefilename:\n");gets(fname);fp=fopen(fname,"rb+");}if(!fp){printf("Filenotfound.\n");return;}

ch1=fgetc(fp);if(feof(fp)){fclose(fp);return;}11.4字符文件應(yīng)用(續(xù)11)while(1){ch2=fgetc(fp);if(feof(fp))break;if(ch1=='/'&&ch2=='

')pos1=ftell(fp)

2;if(ch1=='*'&&ch2=='/'){pos2=ftell(fp)

1;fseek(fp,pos1,SEEK_SET);

for(;pos1<=pos2;pos1++){charch=fgetc(fp);if(ch!='\r'&&ch!='\n')/*回車符與換行符不覆蓋*/{fseek(fp,

1L,1);fputc('',fp);fseek(fp,0L,1);}}}ch1=ch2;}

fclose(fp);}11.4字符文件應(yīng)用(續(xù)12完)例11.8

輸入一句英文,將其作為一行,添加進(jìn)文本文件B.TXT中。#include"stdio.h"voidmain(){chars[81];FILE

fp;charch,

p;fp=fopen("B.TXT","a");/

字符文件添加寫方式

/

printf("Inputastring:\n");gets(s);fputs(s,fp);fputc('\n',fp);fclose(fp);}問題與思考:文件B.TXT需要事先建立嗎?11.5二進(jìn)制文件應(yīng)用例11.9

編程實現(xiàn)文件復(fù)制程序。要求源文件名和目的文件名可以用命令行參數(shù)提供,也可以提示從鍵盤輸入。

#include"stdio.h"#include"string.h"voidmain(intargc,char

argv[]){FILE

fr,

fw;intch;charsfn[81],dfn[81];if(argc==3){strcpy(sfn,argv[1]);strcpy(dfn,argv[2]);}else{printf("InputSourcefilename:");gets(sfn);printf("InputDestinationfilename:");gets(dfn);}11.5二進(jìn)制文件應(yīng)用(續(xù)1)fr=fopen(sfn,"rb");/

二進(jìn)制只讀方式打開源文件

/

if(!fr){printf("Sourcefile%snotfound.\n",sfn);return;}fw=fopen(dfn,"wb");/

二進(jìn)制只寫方式打開目標(biāo)文件

/if(!fw){printf("Destinationfile%scannotbecreated.\n",dfn);return;}ch=fgetc(fr);/*典型循環(huán)結(jié)構(gòu)(一)*/while(!feof(fr)){fputc(ch,fw);ch=fgetc(fr);}fcloseall();}11.5二進(jìn)制文件應(yīng)用(續(xù)2)例11.10建立源程序文件f1.c,從鍵盤輸入N個實數(shù),將其寫入一個二進(jìn)制文件A1.DAT。再建立一個源程序文件f2.c,從A1.DAT中讀出這N個實數(shù),然后進(jìn)行由小到大排序,寫入另一個二進(jìn)制文件A2.DAT。最后,建立一個源程序文件f3.c,從A2.DAT中讀出排序后的N個實數(shù),并顯示在屏幕上。源程序參見教材p295-296.11.5二進(jìn)制文件應(yīng)用(續(xù)3)例11.11

刪除一個正文文件中的大寫英文

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論