版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
一、文本流和二進制流二、流文件三、文件的打開函數(shù)fopen和關閉函數(shù)fclose四、格式讀寫fprintf和fscanf函數(shù)五、出錯測試或清除函(feof,ferror,clearerr)第13章文件1一、文本流和二進制流第13章文件1一、文本流和二進制流內(nèi)存中的信息會由于程序運行的結束而消失。程序運行的結果需要另外穩(wěn)定的介質加以永久保存,這種可以長期保留數(shù)據(jù)的存儲設備稱為磁盤文件。下面幾種是有影響的存儲方式:
1.ANSIC運行庫緩沖流的輸出輸出操作
2.C運行庫低級輸出輸出操作
3.iotream類提供的I/O操作
4.DOS或WINDOWSAPI端口操作5.MicrosoftFoundation類庫的文件操作
2一、文本流和二進制流2在C/C++中流可分為兩類:
1)文本流(textstream);1)二進制流(binarystream)文本流中的數(shù)據(jù)以字符形式出現(xiàn),文本以行作為結束。
圖數(shù)據(jù)的流入流出是一個相對概念
流入cout<<b輸出輸入cin>>a流入
磁盤
內(nèi)存緩沖區(qū)
內(nèi)存數(shù)據(jù)區(qū)
鍵盤stdinstdout顯示器stderr打印機stdprn3在C/C++中流可分為兩類:圖數(shù)據(jù)的流入流出是一個二、流文件流文件是C運行庫函數(shù)中由FILE結構有效處理的硬件設備的邏輯描述。在這個稱為標準文件I/O系統(tǒng)中,定義了三個文本流:stdin,stdout和stderr。一般對如下前3個標準設備,系統(tǒng)構筑了流文件的索引方式,其相應的非緩沖區(qū)的文件代號一并羅列如下:
硬件設備預定義的流文件或流對象設備代號或句柄鍵盤(標準輸入)stdincin0顯示器(標準輸出)stdoutcout1顯示器(標準錯誤)stderrcerr2串行口(標準輔助)stdaux3打印機(標準打印)stdprnclog44二、流文件4描述流文件的FILE數(shù)據(jù)結構隨編譯器版本的不同而相異,下面的描述摘自微軟VC6.0頭文件stdio.h,該結構的具體聲明如下:struct_iobuf{char*_ptr;//1索引數(shù)據(jù)流內(nèi)容的位置指針int_cnt;//2當前的定位標志數(shù)char*_base;//3緩沖區(qū)基準位置int_flag;//4文件操作模式標記int_file;//5文件的代號int_charbuf;//6字符緩沖信息int_bufsiz;//7緩沖區(qū)大小char*_tmpfname;//8臨時文件名};typedefstruct_iobufFILE;5描述流文件的FILE數(shù)據(jù)結構隨編譯器版本的對于該結構軟件供應商并未逐一指明其中每一數(shù)據(jù)成員的詳細含義,標準輸入輸出函數(shù)的用戶不要冒然直接去操作其中的成員,而通過相應的函數(shù)間接進行。 三個預定義的流文件在vc6.0的stdio.h中通過通過外部說明語句和宏:
externFILE_iob[]; #definestdin(&_iob[0]) #definestdout(&_iob[1]) #definestderr(&_iob[2]) 就已經(jīng)在內(nèi)存中構建,因此不對這三個標準的I/O設備進行建立和清除工作。但其它的流文件需要程序員調用相關的函數(shù),進行規(guī)則的內(nèi)存分配和釋放工作。6對于該結構軟件供應商并未逐一指明其中每一數(shù)據(jù)成三、文件的打開函數(shù)fopen和關閉函數(shù)fclose1.文件的打開函數(shù)fopen文件的打開函數(shù)fopen是為要操作的磁盤文件對應的數(shù)據(jù)結構分配內(nèi)存的函數(shù),這是一個構建FILE的數(shù)據(jù)結構變量的初始化函數(shù),系統(tǒng)通過調用類似malloc的堆內(nèi)存分配函數(shù)完成了FILE型結構變量的內(nèi)存分配。下面是fopen函數(shù)一個簡約的函數(shù)原型:
FILE*fopen(constchar*filename,constchar*mode);函數(shù)返回一個指向堆空間的FILE*型的流文件指針。不如確切地說該函數(shù)在堆空間誕生了一個FILE型結構變量。7三、文件的打開函數(shù)fopen和關閉函數(shù)fclose7兩個constchar*型的入口參數(shù)對上面的結構成員執(zhí)行了部分初始化賦值。第一個參數(shù)filename是定位磁盤文件路徑的文件名,該文件名通常是雙引號括起來的只讀字符串。在使用含路徑的文件名時,注意“\”的使用,對于硬盤中的文件d:\mydocu_1\ex.cpp應寫成“d:\\mydocu_1\\ex1.cpp”或進行如下的初始賦值:constchar*filename="d:\\mydocu_1\\ex1.cpp"; 第二個以只讀字符串的形式出現(xiàn)的參數(shù)mode,界定文件訪問操作的模式。(其有效的取值組合和含義見下一頁)8兩個constchar*型的入口參數(shù)對上mode含義"r"以readonly方式打開一個文本文件,如果輸入文件不存在或未找到fopen失敗"w"以writeonly方式打開一個文本文件,如果輸出文件已存在,內(nèi)容將全覆蓋"a"以寫和append方式在文本文件末尾追加,如果它不存在則先建立該文件"r+"以讀或寫的方式打開一個必須已經(jīng)存在的文本文件"w+"以讀或寫的方式打開一個空文件,如果給定的文件名存在原來的內(nèi)容將被沖洗"a+"以讀/寫和追加方式打開文件,如果該文件不存在則先建立它9mode含義9"rb"以只讀方式打開一個binary輸入文件,如果文件不存在或未找到fopen失敗"wb"以只寫方式打開一個二進制輸出文件,如果文件已存在,內(nèi)容將全覆蓋"ab"以append方式在binary文件末尾追加,如果它不存在則先建立該文件"rb+"以讀或寫的方式打開一個必須已經(jīng)存在的二進制文件"wb+"以讀或寫的方式打開一個空binary文件,如果文件名存在原來的內(nèi)容將被銷毀"ab+"以讀和追加方式打開二進制文件,如果該文件不存在則先建立它10"rb"以只讀方式打開一個binary輸指定文件的缺省操作類型取決于一個全局變量_fmode,vc6.0里在頭文件stdlib.h中聲明為[externint_fmode;],系統(tǒng)設置的默認值是文本方式即:_fmode=O_TEXT=0x4000如果從文本方式切換為二進制模式,可以在程序中令:_fmode=O_BINARY;如果在打開文件發(fā)生錯誤,則fopen都返回NULL即0,其潛在的原因有:
a.以讀模式打開一個并不存在的文件
b.打開一個無權操作的文件(如該文件已標明只讀或隱藏屬性試圖寫追加打開)
c.以追加方式對文件操作但磁盤空間不足11指定文件的缺省操作類型取決于一個全局變量2.文件的關閉函數(shù)fclose函數(shù)fclose專用于釋放由函數(shù)fopen申請的堆空間,及時完成緩沖區(qū)數(shù)據(jù)的到位。fclose的函數(shù)原型為:
intfclose(FILE*fp);fclose的函數(shù)原型為:intfclose(FILE*fp);其中入口形參匹配函數(shù)fopen返回的指針值,函數(shù)fclose調用成功返回數(shù)值0,否則返回EOF即-1。該函數(shù)不操作預定義的流文件stdin,stdout和stderr,它們是指向全局結構變量的指針。這樣函數(shù)調用:
fclose(fp);就關閉了先前由fopen函數(shù)打開的文件指針所對應的堆空間。122.文件的關閉函數(shù)fclose12四、格式讀寫fprintf和fscanf函數(shù)
1.fprintf輸出函數(shù)fprintf輸出函數(shù)的一般形式為:
intfprintf(FILE*pTarget,constchar*format,argument_list); intfprintf(流文件的目的地,格式控制串,參量列表);
fprintf函數(shù)格式控制串與printf中的相同。將fprintf的第一個形參pTarget取為實參stdout,其調用格式相當于printf函數(shù)。即
fprintf(stdout,格式控制串,參量列表);
相當于:printf(格式控制串,參量列表);
13四、格式讀寫fprintf和fscanf函數(shù)13在使用fprintf將內(nèi)存數(shù)據(jù)寫到磁盤文件之前,先要指明磁盤文件的目的所在,因此通過fopen函數(shù)的寫模式獲得目標地址。如:FILE*fpWrite=fopen(writeFile,"w");如此之后就可以調用的fprintf函數(shù).如:fprintf(fpWrite,format,v_list);fprintf(流文件目的地,格式控制串,變量列表);14在使用fprintf將內(nèi)存數(shù)據(jù)寫到磁盤文件之2.fscanf輸入函數(shù)fscanf函數(shù)的一般形式為:
intfscanf(FILE*pSource,constchar*format,address_list); intfscanf(流文件的來源處,格式控制串,變量的地址列表);將fscanf的第一個形參pSource實參化為stdin,其調用格式相當于scanf函數(shù)。即:
fscanf(stdin,格式控制串,變量地址1,變量地址2....變量地址n);相當于:
scanf(格式控制串,變量地址1,變量地址2....變量地址n);
152.fscanf輸入函數(shù)15在調用fscanf函數(shù)將磁盤源文件中的數(shù)據(jù)送到變量所占住的內(nèi)存之前,先應指明待讀的磁盤文件,因此借助fopen函數(shù)的讀模式得到數(shù)據(jù)源流的地址如:FILE*fpRead=fopen(readFile,"r");如此之后就可以調用輸入函數(shù)fscanf。格式為:
fscanf(fpRead,format,address_list);16在調用fscanf函數(shù)將磁盤源文件中的數(shù)據(jù)送到[例]格式轉換處理一個結構變量.#include<stdio.h>typedefstructSData{intnLineset;floatfAdjust;intnPoint; floatfXa; floatfYa; floatfZa; }CData;voidOutputData(constchar*filename,constCData&d) {FILE*fp=fopen(filename,"w");
fprintf(fp,"%d,%f,%d\n",d.nLineset,d.fAdjust,d.nPoint);//1 fprintf(fp,"%f,%f,%f\n",d.fXa,d.fYa,d.fZa);//2 fclose(fp); }17[例]格式轉換處理一個結構變量.17voidInputData(constchar*filename,CData&d) {FILE*fp=fopen(filename,"r");fscanf(fp,"%d,%f,%d",&d.nLineset,&d.fAdjust,&d.nPoint);fscanf(fp,"%f,%f,%f",&d.fXa,&d.fYa,&d.fZa);//2 fclose(fp);} 1818voidmain(void){CDatas={1,2,3,4,5,6};OutputData("c:\\sdata.out",s);CDatad;InputData("c:\\sdata.out",d);OutputData("c:\\cdata.out",d); }在文件c:\cdata.out中輸出結果為:1,2.000000,34.000000,5.000000,6.000000在文件c:\sdata.out中輸出結果為:1,2.000000,34.000000,5.000000,6.00000019voidmain(void)19五、出錯測試或清除函(feof,ferror,clearerr)1.feof函數(shù)測試文件結束標志feof函數(shù)的原型為:
intfeof(FILE*stream);該函數(shù)的調用格式常為:
while(!feof(stream))讀寫循環(huán)體;2.ferror函數(shù)測試流中的錯誤ferror函數(shù)的原型為:
intferror(FILE*stream);3.clearerr函數(shù)清除錯誤標志為0 clearerr函數(shù)原型為:
[voidclearerr(FILE*stream);]20五、出錯測試或清除函(feof,ferror,clearer
六、字符和字符串讀寫函數(shù)
七、無格式轉換的讀寫函數(shù)fread和fwrite
八、文件的定位
九、一個簡單的讀寫存盤程序步驟第13章文件21第13章文件21六、字符和字符串讀寫函數(shù)
1.讀取單個字符的fgetc函數(shù)
fgetc函數(shù)的原型為:intfgetc(FILE*pSrcFile);
FILE*型的入口形參指明讀取操作的來源,實參匹配fopen打開的磁盤文件或stdin。該函數(shù)從磁盤文件的當前位置讀取一個字符,定位源磁盤文件的位置指針向后移動一個字節(jié)。如果該指針到達文件末尾,fgetc函數(shù)返回EOF。
注意例程getc與函數(shù)fgetc作用相同但可以作為函數(shù)和宏出現(xiàn)。getchar()例程與getc(stdin)一致,亦可以作為函數(shù)和宏出現(xiàn)。22六、字符和字符串讀寫函數(shù)22[例]fgetc.cpp#include<stdio.h>voidmain(void){FILE*fpGet=fopen("fgetc.cpp","r"); if(fpGet==NULL){printf("fopenfailed\n");return;}inti=0; charbuffer[512]; while(feof(fpGet)==0&&i<512)buffer[i++]=fgetc(fpGet); buffer[i]='\0'; printf("%s\n",buffer); //fclose(fpGet); }//程序運行的結果顯示fgetc.cpp在屏幕上23[例]fgetc.cpp232.存寫單個字符的fputc函數(shù)fputc函數(shù)的原型為:intfputc(intch,FILE*pDstFile);fputc函數(shù)的第一個形參ch正是要存寫到第二個形參pDstFile關聯(lián)的磁盤文件中去的字符,該函數(shù)返回第一個入口形參的實參值。pDstFile匹配一個fopen返回的流文件指針或stdout,調用失敗返回EOF。242.存寫單個字符的fputc函數(shù)24[例]fputc.cpp#include<stdio.h>voidmain(void){FILE*fpGet=fopen("fputc.cpp","r");if(fpGet==NULL){printf("fopenfailed\n");return;}FILE*fpPut=fopen("fputc.xpp","w"); if(fpPut==NULL){printf("fopenfailed\n");return;} while(!feof(fpGet))//while(feof(fpGet)==0)fputc(fgetc(fpGet),fpPut);fclose(fpGet);fclose(fpPut);}25[例]fputc.cpp25程序運行之后即將上面的fputc.cpp源程序轉存到fputc.xpp中。上面單個輸入輸出函數(shù)其返回類型是int型的數(shù)值,雖然處理的是僅一個字節(jié)長的字符。因此接受這些函數(shù)的結果的變量最好定義成int型變量即:intch1=fgetc(pSrcFile); 函數(shù)一般地會自動進行截斷整型高位數(shù)的處理而只存寫低位。而能不失包容性地應付占兩個字節(jié)的重要結尾信息EOF(-1)。26程序運行之后即將上面的fputc.c3.按行讀文本串fgets函數(shù)函數(shù)fgets的原型為:char*fgets(char*pDstBuffer,intnum,FILE*pSrcFile); FILE*型的入口形參pSrcFile定位數(shù)據(jù)的來源,匹配實參stdin或fopen函數(shù)讀模式返回的流文件的指針,從中讀取num-1個字符到char*的入口形參pDstBuffer標明的字符緩沖區(qū),pDstBuffer也就是該函數(shù)的返回地址。如果在讀取num-1個字符之前遇到換行符\n則讀入結束;然后添補一個\0字符,以表示字符串的規(guī)則結束。暗地里定位源磁盤文件的位置指針向后移動字符緩沖區(qū)實際擁有的字節(jié)數(shù).pDstBuffer匹配一個足夠大的字符數(shù)組.273.按行讀文本串fgets函數(shù)27[例]fgets.cpp
#include<stdio.h>voidmain(void){FILE*fp=fopen("fgets.cpp","r");if(fp==NULL){printf("fopenfailed\n");return;}charsBuffer[128]; for(intk=0;k<9;k++) if(fgets(sBuffer,128,fp)!=NULL)printf("%s",sBuffer);fclose(fp);}//程序運行的結果顯示fgets.cpp在屏幕上。28[例]fgets.cpp284.按行寫文本串fputs函數(shù)
函數(shù)fputs的原型為:
intfputs(constchar*pSrcBuffer,FILE*pDstFile);文本文件的操作一般按行進行,一行一行地讀一行一行地寫,fgets函數(shù)執(zhí)行按行讀的操作,函數(shù)fputs則按行寫。
fputs函數(shù)將第一個形參定位的只讀字符串送到送到第二個形參指明的目的文件中的當前位置。如果調用成功函數(shù)返回正數(shù),在出現(xiàn)錯誤時返回EOF。294.按行寫文本串fputs函數(shù)29[例]fputs.cpp#include<stdio.h>voidmain(void){ FILE*fpRead=fopen("fputs.cpp","r");if(fpRead==NULL){printf("fopenrfailed\n");return;}FILE*fpWrite=fopen("fputsw.cpp","w"); if(fpWrite==NULL){printf("fopenwfailed\n");return;} 30[例]fputs.cpp30chars[81]; while(!feof(fpRead))//while(feof(fpRead)==0) if(fgets(s,81,fpRead)!=NULL) {fputs(s,fpWrite);printf("%s",s);} fclose(fpWrite);}
//程序運行顯示fputs.cpp在屏幕上同時拷貝了一個備份在磁盤文件fputsw.cpp中31chars[81];七、無格式轉換的讀寫函數(shù)fread和fwrite函數(shù)直接讀寫磁盤文件的二進制數(shù)據(jù),讀寫過程數(shù)據(jù)的信息未發(fā)生轉換。因而空間效率和時間效率都比較高。1.函數(shù)fread的原型為:
size_tfread(void*pDst,size_tsize,size_titems,FILE*pSrc);第一個參數(shù)pDst定位讀取數(shù)據(jù)的存放位置,匹配任意集合類型的起始地址。 第二個參數(shù)size指出數(shù)據(jù)的類型大小;size=sizeof(type)。
32七、無格式轉換的讀寫函數(shù)fread和fwrite32第三個參數(shù)items指出數(shù)據(jù)的最大項數(shù),常對應數(shù)組的維數(shù),單一變量或對象常取1。第四個參數(shù)是FILE*型的入口形參pSrc,指明讀入數(shù)據(jù)的來源。fread返回實際讀取的項數(shù),函數(shù)從輸入文件中最多讀取items項數(shù),每一項含有size字節(jié),并將它們放入pDst起始的內(nèi)存中。如果錯誤發(fā)生則所讀的結果是游移的。與pSrc關聯(lián)的位置指針向后移動實際讀取的字節(jié)數(shù)。33第三個參數(shù)items指出數(shù)據(jù)的最大項數(shù),常對2.fwrite存寫函數(shù)函數(shù)fwrite的原型為:
size_tfwrite(constvoid*pSrc,size_tsize,size_titems,FILE*pDst);一般地fread總是讀取原先由frwite存寫的二進制數(shù)據(jù);第一個參數(shù)入口形參pSrc定位所寫數(shù)據(jù)的源位置,匹配任意集合類型的起始地址。 第四個參數(shù)入口形參pDst指向待存寫的目的地即與pDst相關聯(lián)的磁盤文件。其余兩個參數(shù)同fread函數(shù)。
342.fwrite存寫函數(shù)34函數(shù)fwrite返回實際所存寫的數(shù)據(jù)項的個數(shù),如出現(xiàn)錯誤返回值可少于items。fwrite函數(shù)從pSrc定位地址起盡量轉送items個數(shù)據(jù)項到輸出流文件中,位置指針遞增實際所寫的字節(jié)數(shù)。上面兩個函數(shù)都存在void*的指針用于寬泛地定位內(nèi)存的地址,但由于其含糊性必伴隨具有size_t類型的具體參數(shù)嚴格劃定數(shù)據(jù)的邊界,這是void*型形參函數(shù)的共性。 一般地fread總是讀取原先由frwite存寫的二進制數(shù)據(jù)。35函數(shù)fwrite返回實際所存寫的數(shù)據(jù)項的個[例]直接隨機方式處理結構變量和數(shù)組#include<stdio.h>typedefstructSData{intnLineset;floatfAdjust;intnPoint; floatfXa; floatfYa;floatfZa; }CData;voidWriteData(CDatapSrc[],intn,FILE*fpDst){switch(n){case1: fwrite(pSrc,sizeof(CData),1,fpDst);break; default: fwrite(pSrc,sizeof(CData),n,fpDst);}}inlinevoidReadData(CData*pDst,intn,FILE*fpSrc){fread(pDst,sizeof(CData),n,fpSrc);}36[例]直接隨機方式處理結構變量和數(shù)組36voidPrintData(constCData&d){printf(“%4d,%4.1f,%4d,%4.1f,%4.1f,%4.1f\n”,d.nLineset,d.fAdjust,d.nPoint,d.fXa,d.fYa,d.fZa);}voidmain(void) {CDatas={0,1,2,3,4,5};CDatad[]={1,2,3,4,5,6,2,3,4,5,6,7,3,4,5,6,7,8};FILE*fpWrite=fopen("c:\\cdata.dat","w"); if(fpWrite==NULL){printf("fopenwfailed\n");return;} WriteData(&s,1,fpWrite);WriteData(d,3,fpWrite); fclose(fpWrite);FILE*fpRead=fopen("c:\\cdata.dat","r");
37voidPrintData(constCData&if(fpRead==NULL){printf("fopenrfailed\n");return;}CDatab[4];ReadData(b,3,fpRead);ReadData(b+3,1,fpRead);for(intk=0;k<4;k++)PrintData(b[k]);}
c:\cdata.dat文件的長度為4*6*4=96個字節(jié),屏幕顯示結果為:0,1.0,2,3.0,4.0,5.01,2.0,3,4.0,5.0,6.02,3.0,4,5.0,6.0,7.03,4.0,5,6.0,7.0,8.038if(fpRead==NULL)38fread和fwrite函數(shù)因其void*入口參數(shù)而可以匹配任意類型的變量地址,而稱為隨機讀寫函數(shù)。但實際上數(shù)據(jù)的類型屬性轉移到size_t參數(shù)上去了,這個size_t參數(shù)n=sizeof(type)協(xié)同函數(shù)在定位好的內(nèi)存空間中讀寫數(shù)據(jù)。因此數(shù)據(jù)類型屬性的匹配依然是環(huán)環(huán)相扣不可輕易錯位的。即此類型的函數(shù)操作此類型的數(shù)據(jù)。隨機讀寫應根據(jù)數(shù)據(jù)類型的匹配關系為:voidWriteData(CData*pSrc,intn,FILE*fpDst){fwrite(pSrc,sizeof(CData),n,fpDst);}
voidReadData(CData*pDst,intn,FILE*fpSrc){fread(pDst,sizeof(CData),n,fpSrc);}39fread和fwrite函數(shù)因其void*入八、文件的定位1.ftell函數(shù)告知當前位置FILE結構的聲明中有一個char*型指針成員_ptr即索引數(shù)據(jù)流內(nèi)容的位置指針,該指針潛在地指向當前文件的位置。當用戶首次打開流文件進行讀寫操作時,操作系統(tǒng)把該位置指針設置在文件的開頭。但特別地以追加方式a打開文件時,位置指針定位于文件的結尾處。每次讀寫一個字符時,位置指針向前移動一個字符。如果從文件中讀寫一行文本,位置指針一般移到該行末尾或下一行開始處。40八、文件的定位40ftell函數(shù)告知當前位置函數(shù)ftell的原型為:
longftell(FILE*stream);函數(shù)返回的long型值為指定文件中的當前位置相對于流文件起始位置的字節(jié)偏移量,stream一般匹配fopen函數(shù)打開的文件。[例]ftell.cpp#include<stdio.h> voidmain(void){FILE*stream=fopen("ftell.cpp","rb");doublea[20];fread(a,sizeof(double),20,stream);printf("%d\n",ftell(stream));}//輸出16041ftell函數(shù)告知當前位置函數(shù)ftell的原2.fseek函數(shù)探尋文件的位置函數(shù)fseek用于在一個打開的文件中重新定位文件的位置指針,如果成功返回結果0,否則返回非0值,在不能探尋的設備上返回的結果是不定的。其函數(shù)原型為:
intfseek(FILE*stream,longoffset,intorigin);//fseek(文件指針,偏移量,起始位置);起始位置參量origin的取值范圍必須是如下的宏名或隨后具體的常數(shù),含義為: #defineSEEK_CUR1//文件當前位置 #defineSEEK_END2//文件結束位置 #defineSEEK_SET0//文件開始位置
422.fseek函數(shù)探尋文件的位置42fseek函數(shù)在stream形參所對應的文件中運作,將其中的位置指針變動到新的位置,新的位置由offset算定。偏移量參量offset指出距離origin起始位置的字節(jié)偏移數(shù),正的long型實參表示以起始位置為基準前移offset個字節(jié)作為新的位置,負的實參則后移。 在流上的下一回合操作以新的位置為基準,一般可安全地用于二進制文件。 fseek函數(shù)操作文本文件的結果漂移于回車換行次數(shù)的不確定性。43fseek函數(shù)在stream形參所對應的文件3.rewind函數(shù)反繞到文件開頭位置rewind函數(shù)原型為:
voidrewind(FILE*stream); 函數(shù)rewind重新定位與stream關聯(lián)的位置指針到文件的開頭。函數(shù)調用[rewind(stream);]近似于:(void)fseek(stream,0L,SEEK_SET);但不象fseek,函數(shù)rewind清除文件結束符和stream的出錯標記。443.rewind函數(shù)反繞到文件開頭位置44九、一個簡單的讀寫存盤程序步驟 讀寫存盤操作是程序設計中的重要工作,程序的讀寫操作主要包含如下步驟和特點:
1.構筑待存盤操作的數(shù)據(jù)結構,不同的數(shù)據(jù)結構對應不同的函數(shù);
2.明晰數(shù)據(jù)的來源和走向,屏幕操作利用格式轉換函數(shù)以進行字符處理;
3.格式化輸出一般用于顯示數(shù)據(jù),格式化磁盤輸入常嚴格呼應格式化輸出函數(shù);
4.非格式化函數(shù)直接在內(nèi)存和磁盤之間輸送數(shù)據(jù)無需信息轉換.45九、一個簡單的讀寫存盤程序步驟45一、文本流和二進制流二、流文件三、文件的打開函數(shù)fopen和關閉函數(shù)fclose四、格式讀寫fprintf和fscanf函數(shù)五、出錯測試或清除函(feof,ferror,clearerr)第13章文件46一、文本流和二進制流第13章文件1一、文本流和二進制流內(nèi)存中的信息會由于程序運行的結束而消失。程序運行的結果需要另外穩(wěn)定的介質加以永久保存,這種可以長期保留數(shù)據(jù)的存儲設備稱為磁盤文件。下面幾種是有影響的存儲方式:
1.ANSIC運行庫緩沖流的輸出輸出操作
2.C運行庫低級輸出輸出操作
3.iotream類提供的I/O操作
4.DOS或WINDOWSAPI端口操作5.MicrosoftFoundation類庫的文件操作
47一、文本流和二進制流2在C/C++中流可分為兩類:
1)文本流(textstream);1)二進制流(binarystream)文本流中的數(shù)據(jù)以字符形式出現(xiàn),文本以行作為結束。
圖數(shù)據(jù)的流入流出是一個相對概念
流入cout<<b輸出輸入cin>>a流入
磁盤
內(nèi)存緩沖區(qū)
內(nèi)存數(shù)據(jù)區(qū)
鍵盤stdinstdout顯示器stderr打印機stdprn48在C/C++中流可分為兩類:圖數(shù)據(jù)的流入流出是一個二、流文件流文件是C運行庫函數(shù)中由FILE結構有效處理的硬件設備的邏輯描述。在這個稱為標準文件I/O系統(tǒng)中,定義了三個文本流:stdin,stdout和stderr。一般對如下前3個標準設備,系統(tǒng)構筑了流文件的索引方式,其相應的非緩沖區(qū)的文件代號一并羅列如下:
硬件設備預定義的流文件或流對象設備代號或句柄鍵盤(標準輸入)stdincin0顯示器(標準輸出)stdoutcout1顯示器(標準錯誤)stderrcerr2串行口(標準輔助)stdaux3打印機(標準打?。﹕tdprnclog449二、流文件4描述流文件的FILE數(shù)據(jù)結構隨編譯器版本的不同而相異,下面的描述摘自微軟VC6.0頭文件stdio.h,該結構的具體聲明如下:struct_iobuf{char*_ptr;//1索引數(shù)據(jù)流內(nèi)容的位置指針int_cnt;//2當前的定位標志數(shù)char*_base;//3緩沖區(qū)基準位置int_flag;//4文件操作模式標記int_file;//5文件的代號int_charbuf;//6字符緩沖信息int_bufsiz;//7緩沖區(qū)大小char*_tmpfname;//8臨時文件名};typedefstruct_iobufFILE;50描述流文件的FILE數(shù)據(jù)結構隨編譯器版本的對于該結構軟件供應商并未逐一指明其中每一數(shù)據(jù)成員的詳細含義,標準輸入輸出函數(shù)的用戶不要冒然直接去操作其中的成員,而通過相應的函數(shù)間接進行。 三個預定義的流文件在vc6.0的stdio.h中通過通過外部說明語句和宏:
externFILE_iob[]; #definestdin(&_iob[0]) #definestdout(&_iob[1]) #definestderr(&_iob[2]) 就已經(jīng)在內(nèi)存中構建,因此不對這三個標準的I/O設備進行建立和清除工作。但其它的流文件需要程序員調用相關的函數(shù),進行規(guī)則的內(nèi)存分配和釋放工作。51對于該結構軟件供應商并未逐一指明其中每一數(shù)據(jù)成三、文件的打開函數(shù)fopen和關閉函數(shù)fclose1.文件的打開函數(shù)fopen文件的打開函數(shù)fopen是為要操作的磁盤文件對應的數(shù)據(jù)結構分配內(nèi)存的函數(shù),這是一個構建FILE的數(shù)據(jù)結構變量的初始化函數(shù),系統(tǒng)通過調用類似malloc的堆內(nèi)存分配函數(shù)完成了FILE型結構變量的內(nèi)存分配。下面是fopen函數(shù)一個簡約的函數(shù)原型:
FILE*fopen(constchar*filename,constchar*mode);函數(shù)返回一個指向堆空間的FILE*型的流文件指針。不如確切地說該函數(shù)在堆空間誕生了一個FILE型結構變量。52三、文件的打開函數(shù)fopen和關閉函數(shù)fclose7兩個constchar*型的入口參數(shù)對上面的結構成員執(zhí)行了部分初始化賦值。第一個參數(shù)filename是定位磁盤文件路徑的文件名,該文件名通常是雙引號括起來的只讀字符串。在使用含路徑的文件名時,注意“\”的使用,對于硬盤中的文件d:\mydocu_1\ex.cpp應寫成“d:\\mydocu_1\\ex1.cpp”或進行如下的初始賦值:constchar*filename="d:\\mydocu_1\\ex1.cpp"; 第二個以只讀字符串的形式出現(xiàn)的參數(shù)mode,界定文件訪問操作的模式。(其有效的取值組合和含義見下一頁)53兩個constchar*型的入口參數(shù)對上mode含義"r"以readonly方式打開一個文本文件,如果輸入文件不存在或未找到fopen失敗"w"以writeonly方式打開一個文本文件,如果輸出文件已存在,內(nèi)容將全覆蓋"a"以寫和append方式在文本文件末尾追加,如果它不存在則先建立該文件"r+"以讀或寫的方式打開一個必須已經(jīng)存在的文本文件"w+"以讀或寫的方式打開一個空文件,如果給定的文件名存在原來的內(nèi)容將被沖洗"a+"以讀/寫和追加方式打開文件,如果該文件不存在則先建立它54mode含義9"rb"以只讀方式打開一個binary輸入文件,如果文件不存在或未找到fopen失敗"wb"以只寫方式打開一個二進制輸出文件,如果文件已存在,內(nèi)容將全覆蓋"ab"以append方式在binary文件末尾追加,如果它不存在則先建立該文件"rb+"以讀或寫的方式打開一個必須已經(jīng)存在的二進制文件"wb+"以讀或寫的方式打開一個空binary文件,如果文件名存在原來的內(nèi)容將被銷毀"ab+"以讀和追加方式打開二進制文件,如果該文件不存在則先建立它55"rb"以只讀方式打開一個binary輸指定文件的缺省操作類型取決于一個全局變量_fmode,vc6.0里在頭文件stdlib.h中聲明為[externint_fmode;],系統(tǒng)設置的默認值是文本方式即:_fmode=O_TEXT=0x4000如果從文本方式切換為二進制模式,可以在程序中令:_fmode=O_BINARY;如果在打開文件發(fā)生錯誤,則fopen都返回NULL即0,其潛在的原因有:
a.以讀模式打開一個并不存在的文件
b.打開一個無權操作的文件(如該文件已標明只讀或隱藏屬性試圖寫追加打開)
c.以追加方式對文件操作但磁盤空間不足56指定文件的缺省操作類型取決于一個全局變量2.文件的關閉函數(shù)fclose函數(shù)fclose專用于釋放由函數(shù)fopen申請的堆空間,及時完成緩沖區(qū)數(shù)據(jù)的到位。fclose的函數(shù)原型為:
intfclose(FILE*fp);fclose的函數(shù)原型為:intfclose(FILE*fp);其中入口形參匹配函數(shù)fopen返回的指針值,函數(shù)fclose調用成功返回數(shù)值0,否則返回EOF即-1。該函數(shù)不操作預定義的流文件stdin,stdout和stderr,它們是指向全局結構變量的指針。這樣函數(shù)調用:
fclose(fp);就關閉了先前由fopen函數(shù)打開的文件指針所對應的堆空間。572.文件的關閉函數(shù)fclose12四、格式讀寫fprintf和fscanf函數(shù)
1.fprintf輸出函數(shù)fprintf輸出函數(shù)的一般形式為:
intfprintf(FILE*pTarget,constchar*format,argument_list); intfprintf(流文件的目的地,格式控制串,參量列表);
fprintf函數(shù)格式控制串與printf中的相同。將fprintf的第一個形參pTarget取為實參stdout,其調用格式相當于printf函數(shù)。即
fprintf(stdout,格式控制串,參量列表);
相當于:printf(格式控制串,參量列表);
58四、格式讀寫fprintf和fscanf函數(shù)13在使用fprintf將內(nèi)存數(shù)據(jù)寫到磁盤文件之前,先要指明磁盤文件的目的所在,因此通過fopen函數(shù)的寫模式獲得目標地址。如:FILE*fpWrite=fopen(writeFile,"w");如此之后就可以調用的fprintf函數(shù).如:fprintf(fpWrite,format,v_list);fprintf(流文件目的地,格式控制串,變量列表);59在使用fprintf將內(nèi)存數(shù)據(jù)寫到磁盤文件之2.fscanf輸入函數(shù)fscanf函數(shù)的一般形式為:
intfscanf(FILE*pSource,constchar*format,address_list); intfscanf(流文件的來源處,格式控制串,變量的地址列表);將fscanf的第一個形參pSource實參化為stdin,其調用格式相當于scanf函數(shù)。即:
fscanf(stdin,格式控制串,變量地址1,變量地址2....變量地址n);相當于:
scanf(格式控制串,變量地址1,變量地址2....變量地址n);
602.fscanf輸入函數(shù)15在調用fscanf函數(shù)將磁盤源文件中的數(shù)據(jù)送到變量所占住的內(nèi)存之前,先應指明待讀的磁盤文件,因此借助fopen函數(shù)的讀模式得到數(shù)據(jù)源流的地址如:FILE*fpRead=fopen(readFile,"r");如此之后就可以調用輸入函數(shù)fscanf。格式為:
fscanf(fpRead,format,address_list);61在調用fscanf函數(shù)將磁盤源文件中的數(shù)據(jù)送到[例]格式轉換處理一個結構變量.#include<stdio.h>typedefstructSData{intnLineset;floatfAdjust;intnPoint; floatfXa; floatfYa; floatfZa; }CData;voidOutputData(constchar*filename,constCData&d) {FILE*fp=fopen(filename,"w");
fprintf(fp,"%d,%f,%d\n",d.nLineset,d.fAdjust,d.nPoint);//1 fprintf(fp,"%f,%f,%f\n",d.fXa,d.fYa,d.fZa);//2 fclose(fp); }62[例]格式轉換處理一個結構變量.17voidInputData(constchar*filename,CData&d) {FILE*fp=fopen(filename,"r");fscanf(fp,"%d,%f,%d",&d.nLineset,&d.fAdjust,&d.nPoint);fscanf(fp,"%f,%f,%f",&d.fXa,&d.fYa,&d.fZa);//2 fclose(fp);} 6318voidmain(void){CDatas={1,2,3,4,5,6};OutputData("c:\\sdata.out",s);CDatad;InputData("c:\\sdata.out",d);OutputData("c:\\cdata.out",d); }在文件c:\cdata.out中輸出結果為:1,2.000000,34.000000,5.000000,6.000000在文件c:\sdata.out中輸出結果為:1,2.000000,34.000000,5.000000,6.00000064voidmain(void)19五、出錯測試或清除函(feof,ferror,clearerr)1.feof函數(shù)測試文件結束標志feof函數(shù)的原型為:
intfeof(FILE*stream);該函數(shù)的調用格式常為:
while(!feof(stream))讀寫循環(huán)體;2.ferror函數(shù)測試流中的錯誤ferror函數(shù)的原型為:
intferror(FILE*stream);3.clearerr函數(shù)清除錯誤標志為0 clearerr函數(shù)原型為:
[voidclearerr(FILE*stream);]65五、出錯測試或清除函(feof,ferror,clearer
六、字符和字符串讀寫函數(shù)
七、無格式轉換的讀寫函數(shù)fread和fwrite
八、文件的定位
九、一個簡單的讀寫存盤程序步驟第13章文件66第13章文件21六、字符和字符串讀寫函數(shù)
1.讀取單個字符的fgetc函數(shù)
fgetc函數(shù)的原型為:intfgetc(FILE*pSrcFile);
FILE*型的入口形參指明讀取操作的來源,實參匹配fopen打開的磁盤文件或stdin。該函數(shù)從磁盤文件的當前位置讀取一個字符,定位源磁盤文件的位置指針向后移動一個字節(jié)。如果該指針到達文件末尾,fgetc函數(shù)返回EOF。
注意例程getc與函數(shù)fgetc作用相同但可以作為函數(shù)和宏出現(xiàn)。getchar()例程與getc(stdin)一致,亦可以作為函數(shù)和宏出現(xiàn)。67六、字符和字符串讀寫函數(shù)22[例]fgetc.cpp#include<stdio.h>voidmain(void){FILE*fpGet=fopen("fgetc.cpp","r"); if(fpGet==NULL){printf("fopenfailed\n");return;}inti=0; charbuffer[512]; while(feof(fpGet)==0&&i<512)buffer[i++]=fgetc(fpGet); buffer[i]='\0'; printf("%s\n",buffer); //fclose(fpGet); }//程序運行的結果顯示fgetc.cpp在屏幕上68[例]fgetc.cpp232.存寫單個字符的fputc函數(shù)fputc函數(shù)的原型為:intfputc(intch,FILE*pDstFile);fputc函數(shù)的第一個形參ch正是要存寫到第二個形參pDstFile關聯(lián)的磁盤文件中去的字符,該函數(shù)返回第一個入口形參的實參值。pDstFile匹配一個fopen返回的流文件指針或stdout,調用失敗返回EOF。692.存寫單個字符的fputc函數(shù)24[例]fputc.cpp#include<stdio.h>voidmain(void){FILE*fpGet=fopen("fputc.cpp","r");if(fpGet==NULL){printf("fopenfailed\n");return;}FILE*fpPut=fopen("fputc.xpp","w"); if(fpPut==NULL){printf("fop
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 單位管理制度匯編大合集【人事管理篇】十篇
- 單位管理制度合并匯編員工管理
- 《眩暈基礎知識》課件
- 單位管理制度分享大全【職工管理篇】十篇
- 單位管理制度范例合集【員工管理】十篇
- 單位管理制度呈現(xiàn)匯編人力資源管理十篇
- 單位管理制度呈現(xiàn)大合集【職工管理】十篇
- 《離心泵工作點》課件
- 貴都高速某合同段施工組織設計
- 《祝世界好友周快樂》課件
- 成都市農(nóng)貿(mào)市場建設技術要求(2019年版)(完整版)
- 2024-2030年版中國IPVPN服務行業(yè)發(fā)展現(xiàn)狀及投資商業(yè)模式分析報告
- 【7歷期末】安徽省蕪湖市弋江區(qū)2023~2024學年七年級上學期期末考試歷史試卷(含解析)
- 北京市海淀區(qū)2021-2022學年第一學期四年級期末考試語文試卷(含答案)
- 2024-2030年中國企業(yè)大學行業(yè)運作模式發(fā)展規(guī)劃分析報告
- 房地產(chǎn)激勵培訓
- 期末復習試題1(試題)-2024-2025學年二年級上冊數(shù)學北師大版
- 【MOOC】微型計算機原理與接口技術-南京郵電大學 中國大學慕課MOOC答案
- 違章建筑舉報范文
- 音樂制作基礎知識單選題100道及答案解析
- 2024幼師年終工作總結
評論
0/150
提交評論