C語言程序設(shè)計(jì)-提高篇-第3章 文件_第1頁
C語言程序設(shè)計(jì)-提高篇-第3章 文件_第2頁
C語言程序設(shè)計(jì)-提高篇-第3章 文件_第3頁
C語言程序設(shè)計(jì)-提高篇-第3章 文件_第4頁
C語言程序設(shè)計(jì)-提高篇-第3章 文件_第5頁
已閱讀5頁,還剩47頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

C語言程序設(shè)計(jì)

—提高篇第3章文件內(nèi)容概述

文件分類

緩沖文件系統(tǒng)

文件的指針

文件打開與關(guān)閉

文件應(yīng)用教學(xué)目標(biāo)1.概述文件的概念,非緩沖文件系統(tǒng)和緩沖文件系統(tǒng);2.描述文件類型指針的概念及定義方法;3.正確進(jìn)行文件的打開和關(guān)閉操作,及對(duì)打開和關(guān)閉操作的錯(cuò)誤處理;4.正確使用文件的讀寫操作,包括基于字節(jié),數(shù)據(jù)項(xiàng)等的讀寫操作;5.牢記文件的隨機(jī)讀寫方法;6.正確使用文件訪問的錯(cuò)誤檢測及處理方法;文件是指存儲(chǔ)在外部介質(zhì)上,且按文件名訪問的一組信息序列①文本文件(字符代碼文件或ASCII代碼文件)

由一個(gè)一個(gè)字符組成,每一個(gè)字符用一個(gè)ASCII代碼表示,如123.45以ASCII代碼形式存儲(chǔ)到磁盤需要6個(gè)字節(jié)。特點(diǎn):可通過顯示器或打印機(jī)顯示,即可讀,比較直觀。3.1文件分類

②非文本文件(二進(jìn)制文件)是指以數(shù)據(jù)在內(nèi)存中的存儲(chǔ)形式原樣輸出存儲(chǔ)到磁盤上的文件。如123.45在內(nèi)存中以浮點(diǎn)數(shù)形式存儲(chǔ)占4個(gè)字節(jié),不管一個(gè)實(shí)數(shù)多大都占4個(gè)字節(jié)。特點(diǎn):節(jié)省存儲(chǔ)空間,輸入輸出無需轉(zhuǎn)換,速度快,不便閱讀。說明:①一個(gè)C文件是一個(gè)字節(jié)流或二進(jìn)制流,它把數(shù)據(jù)看作是一連串的字符序列(字節(jié)),而不考慮記錄的界限,即C文件并不是由記錄組成的。②由于對(duì)文件的操作要與各種外部設(shè)備發(fā)生聯(lián)系,因此對(duì)文件的輸入輸出(讀寫)過程是通過操作系統(tǒng)來實(shí)現(xiàn)的。對(duì)文件的讀寫都是通過標(biāo)準(zhǔn)的I/O函數(shù)進(jìn)行的。3.2緩沖文件系統(tǒng)(標(biāo)準(zhǔn)IO)和非緩沖文件系統(tǒng)

①緩沖文件系統(tǒng)(又稱標(biāo)準(zhǔn)或高層文件系統(tǒng))

特點(diǎn):對(duì)程序中的每一個(gè)文件都在內(nèi)存中開辟一個(gè)“緩沖區(qū)”。作用:從磁盤文件讀入的數(shù)據(jù)先到“輸入緩沖區(qū)”中,然后再從緩沖區(qū)依次將數(shù)據(jù)送給接收變量。在向磁盤文件輸出數(shù)據(jù)時(shí),先將程序數(shù)據(jù)區(qū)中變量或表達(dá)式的值送到“輸出文件緩沖區(qū)”中,待裝滿后才一起輸出給磁盤文件。目的減少對(duì)磁盤的讀寫次數(shù),即一次可以讀入一批數(shù)據(jù)或輸出一批數(shù)據(jù)。②非緩沖文件系統(tǒng):不由系統(tǒng)自動(dòng)設(shè)置所需緩沖區(qū),而由用戶根據(jù)需要設(shè)置。③新的ANSI標(biāo)準(zhǔn)只建議使用緩沖系統(tǒng),并對(duì)緩沖文件系統(tǒng)的功能進(jìn)行了擴(kuò)充,使既能用于處理字符代碼文件,也能處理二進(jìn)制文件。3.3文件類型指針對(duì)文件的操作是通過文件指針實(shí)現(xiàn)的,關(guān)鍵的概念是“文件指針”。調(diào)用一個(gè)文件需要的信息:文件當(dāng)前讀寫的位置;與該文件對(duì)應(yīng)的內(nèi)存緩沖區(qū)的地址;緩沖區(qū)未被處理的字符數(shù)(字符指針);文件的操作方式。系統(tǒng)內(nèi)部定義了一個(gè)FILE的結(jié)構(gòu)類型。

typedef

struct{

int _fd; //文件號(hào)

int _cleft; //緩沖區(qū)中剩余的字符

int _mode; //文件操作方式

char *_nextc; //下一個(gè)字符位置

char *_buff; //文件緩沖區(qū)位置}FILE;FILE類型保存被使用的文件的有關(guān)信息所有的文件操作都需要FILE類型的指針FILE是庫文件中定義的結(jié)構(gòu)體的別名,FILE定義在stdio.h中注意不要寫成structFILE舉例FILE*fp;3.4文件的打開與關(guān)閉文件必須先打開后使用,并及時(shí)關(guān)閉1)打開文件:是在用戶程序和操作系統(tǒng)之間建立聯(lián)系,程序要把操作的文件的信息通知操作系統(tǒng),如文件名、文件操作方式(讀寫)。讀文件:需要先確定此文件是否存在,并將讀當(dāng)前位置設(shè)定為文件的開頭。寫文件:需要檢查原來是否有同名文件,如有則將該文件的原有內(nèi)容刪除,如無同名文件就建立一個(gè)新文件,然后將寫當(dāng)前位置設(shè)定于文件的開頭,以便從文件開頭寫入數(shù)據(jù)。文件的打開方式:調(diào)用方式fopen("文件名","文件操作方式");功能:返回一個(gè)指向該文件的指針或錯(cuò)誤標(biāo)志NULL。為避免出錯(cuò),常用以下方法來打開文件FILE*fp;

if((fp=fopen(“文件名”,“使用文件方式”))==NULL){

printf(”cannotopenthisfile.\n”);

exit(0); //正常中止程序}文件的打開模式打開模式描述r只讀,打開已有文件,不能寫w只寫,創(chuàng)建或打開,覆蓋已有文件a追加,創(chuàng)建或打開,在已有文件末尾追加r+讀寫,打開已有文件w+讀寫,創(chuàng)建或打開,覆蓋已有文件a+讀寫,創(chuàng)建或打開,在已有文件末尾追加t按文本方式打開(缺省)b按二進(jìn)制方式打開2)文件的關(guān)閉:調(diào)用方式fclose(文件指針變量);例如:fclose(fp1);功能:關(guān)閉一個(gè)已打開的文件(釋放文件信息區(qū))返回值:若成功,返回0,若出錯(cuò),返回EOF(-1)3)文件結(jié)尾標(biāo)志:EOF說明:釋放文件的有關(guān)信息區(qū);將輸出文件緩沖區(qū)的內(nèi)容(無論緩沖區(qū)是否為滿)都輸出寫入文件,然后關(guān)閉文件,這樣可防止丟失本來應(yīng)寫入文件的數(shù)據(jù)。不用的文件應(yīng)關(guān)閉,防止數(shù)據(jù)破壞丟失

3.5.1fputc函數(shù)和fgetc函數(shù)

1.fputc(ch,fp)函數(shù)功能:把一個(gè)字符寫到指定文件中去。

2.fgetc(fp)函數(shù)功能:從指定文件讀入一個(gè)字符。

fgetc函數(shù)的調(diào)用形式為

ch=fgetc(fp)

3.5文件的讀寫

從磁盤文件順序讀入字符并在屏幕顯示出,可以:

ch=fgetc(fp);

while(ch!=EOF){

putchar(ch);Ch=fgetc(fp);}注:判別文件結(jié)束函數(shù)feof(fp)

用來測試fp所指的文件當(dāng)前狀態(tài)是否“文件結(jié)束”。如果是文件結(jié)束,函數(shù)feof(fp)的值為1(真),否則為0(假).例1.從鍵盤輸入一些字符,逐個(gè)送到磁盤上去直到輸入“#”為止。#include<stdio.h>#include<stdlib.h>main(){FILE*fp;charch,filename[10];

printf(“Inputfilename:");

scanf("%s",filename);

if((fp=fopen(filename,"w"))==NULL){printf("cannotopenfile\n");exit(0);}

ch=getchar();printf(“Inputachar:");

ch=getchar();

while(ch!='#'){

fputc(ch,fp);putchar(ch);

ch=getchar();}

fclose(fp);}例2.(例13.2)將一個(gè)磁盤文件的信息復(fù)制到另一個(gè)磁盤文件中#include<stdio.h>main(){FILE*in,*out;charch,infile[10],outfile[10];

printf(“Entertheinfilename:\n”);

scanf(“%s”,infile);/*infile

輸入文件已存在*/

printf(“Entertheoutfilename:\n”);

scanf(“%s”,outfile);

if(in=fopen(infile,”r”))==NULL)/*打開讀文件*/{printf(“cannotopeninfile\n”);exit(0);}

if(out=fopen(outfile,”w”))==NULL)/*打開建立寫文件*/{printf(“cannotopenoutfile\n”);exit(0);}

while(!feof(in)){ch=fgetc(in);fputc(ch,out);}

fclose(in);

fclose(out);}3.5.2fread函數(shù)和fwrite函數(shù)(數(shù)據(jù)塊(二進(jìn)制形式)的讀寫)

fread(buffer,size,count,fp)功能:從fp

所指文件讀入count個(gè),大小為size的字節(jié)數(shù)據(jù)塊,存入buffer(指針)所指存儲(chǔ)單元。函數(shù)返回值為count的值,即輸入數(shù)據(jù)的完整個(gè)數(shù)。如遇文件結(jié)束或出錯(cuò)返回0。

fwrite(buffer,size,count,fp)功能:從buffer所指存儲(chǔ)單元取count個(gè),大小為zsize字節(jié)的數(shù)據(jù)塊,存到fp所指文件。函數(shù)返值為count的值,即輸出數(shù)據(jù)的完整個(gè)數(shù)。如遇文件結(jié)束或出錯(cuò)返回0。數(shù)據(jù)塊(二進(jìn)制形式)的讀寫

fread(buffer,size,count,fp)

fwrite(buffer,size,count,fp)說明:buffer為輸入輸出在內(nèi)存中存放的首地址;size為讀、寫的字節(jié)數(shù),即數(shù)據(jù)塊的大??;count為輸入輸出的數(shù)據(jù)項(xiàng)的個(gè)數(shù);fread()和fwrite()用于二進(jìn)制文件的輸入輸出。#include<stdio.h>例3,(例13.3)#defineSIZE4struct

student_type{charname[10];intnum;intage;charaddr[15];}stud[SIZE];voidsave(){FILE*fp;

inti;

if((fp=fopen(“stu_list”,“wb”))==NULL)/*為輸出打開一個(gè)二進(jìn)制文件*/{printf("cannotopenfile\n");return;}for(i=0;i<SIZE;i++)

if(fwrite(&stud[i],sizeof(structstudent_type),1,fp)!=1)

printf("filewriteerror\n");

fclose(fp);}main(){inti;

for(i=0;i<SIZE;i++)

scanf("%s%d%d%s",stud[i].name,&stud[i].num,&stud[i].age,stud[i].addr);save();}

3.5.3fprintf函數(shù)和fcanf函數(shù)

1.格式化的輸出

fprintf(fp,格式字符串,輸出項(xiàng)表列)功能:將輸出按格式串的規(guī)定輸出到fp指文件。

2.格式化的輸入

fscanf(fp,格式字符串,輸入項(xiàng)表列)功能:從fp所指文件按格式串規(guī)定讀入數(shù)據(jù)。

#include<stdio.h> #include<process.h> #include<string.h> voidmain() { FILE*fp; charname[10];

intnum; floatscore;

if((fp=fopen("file3.txt","w+"))==NULL) {

printf("cannotopenthisfile.\n"); exit(0); }

printf("entername,num,score:");

scanf("%s%d%f",name,&num,&score);while(strlen(name)>1) {

fprintf(fp,"%s%d%f\n",name,num,score);

printf("enter

name,num,score:");

scanf("%s%d%f",name,&num,&score); }

rewind(fp);

while(fscanf(fp,"%s%d%f",name,&num, &score)!=EOF) printf("%-10s,%6d,%6.2f\n",name,num,score);

fclose(fp);}輸出:

zhangsan 501 90.00

liming 502 85.00

gaofei 503 95.00

輸入:entername,num,score:zhangsan 0501 90

entername,num,score:liming 0502 85

entername,num,score:gaofei 0503 95entername,num,score:0 0 03.5.4fgets函數(shù)和fputs函數(shù)1.文件的字符串的輸入處理。

fgets(str,n,fp) 字符串輸入函數(shù)其功能是從fp指定的文件中讀取一個(gè)字符串,若滿足以下條件讀取結(jié)束:①已讀取n-1個(gè)字符,②當(dāng)前讀取到的字符是回車符,③已讀取到文件尾。讀取的字符個(gè)數(shù)至多n-1個(gè),余下的一個(gè)字節(jié)空間作為加“\0”串結(jié)束符。讀取回車符時(shí),也作為一個(gè)字符送入由str所指的內(nèi)存緩沖區(qū)。然后再加一個(gè)字符結(jié)束符“\0”str為數(shù)組名或字符指針;n為讀取字符個(gè)數(shù)5.4fgets函數(shù)和fputs函數(shù)2.文件的字符串輸出處理。

fputs(str,fp) 字符串輸出(寫)函數(shù)其功能是將str所指定的字符串寫到fp指向的文件中。與fgets()函數(shù)在輸入字符串自動(dòng)加“\0”特性對(duì)應(yīng),fputs()函數(shù)在將C字符串寫入文件時(shí)其末尾的“\0”字符自動(dòng)舍去。5.4fgets函數(shù)和fputs函數(shù)#include<stdio.h>

#include<string.h>voidmain(){ FILE*fp;charstr[16];

if((fp=fopen(“file2.txt”,”w”))==NULL){printf(“cannotopenthisfile.\n”); exit(0);}

while(strlen(gets(str))>0)

fputs(str,fp);

fclose(fp);

if(fp=fopen(“file2.txt”,”r”))==NULL{

printf(“cannotopenthisfile.\n”); exit(0);} while(fgets(str,16,fp)!=NULL)

printf(“%s\n”,str);

fclose(fp);}函數(shù)功能函數(shù)功能fputc輸出字符fprintf格式化輸出fgetc輸入字符fscanf格式化輸入putc輸出字符putw輸出一個(gè)字getc輸入字符getw輸入一個(gè)字fwrite輸出數(shù)據(jù)塊fputs輸出字符串fread輸入數(shù)據(jù)塊fgets輸入字符串文件的讀寫回顧:fgetc(),fputc()fgets(),fputs()fscanf(),fprintf()這些函數(shù)都是按順序讀/寫文件3.5文件的隨機(jī)讀寫解決的辦法:把文件指針移到指定的位置即可。關(guān)鍵步驟:文件的定位。3.5文件的隨機(jī)讀寫問題:要求打開文件后,對(duì)指定位置上的數(shù)據(jù)進(jìn)行讀寫操作,減少一些不必要的中間環(huán)節(jié)。一、對(duì)文件隨機(jī)存取的思想對(duì)一個(gè)文件流,可以取指定位置的記錄和更新指定位置的記錄。如:對(duì)一個(gè)文件流可以有兩種目的:從第i個(gè)字節(jié)開始,讀取k個(gè)字節(jié)的內(nèi)容把k個(gè)字節(jié)的內(nèi)容寫到從第i個(gè)字節(jié)開始的后面的字節(jié)中。存在的問題:讀取的內(nèi)容是否滿足我們的要求?3012結(jié)束標(biāo)志……kin1二、隨機(jī)存取的應(yīng)用隨機(jī)存取文件適合于具有固定長度記錄的文件程序可以很方便的訪問到指定位置處的記錄。訪問…100200300400500…結(jié)束標(biāo)志0100個(gè)字節(jié)100個(gè)字節(jié)100個(gè)字節(jié)100個(gè)字節(jié)100個(gè)字節(jié)100個(gè)字節(jié)三、隨機(jī)存取的目的1.方便、快捷2.只改變指定位置后的固定長度字節(jié)的內(nèi)容(不會(huì)破壞其它的數(shù)據(jù))結(jié)束標(biāo)志…讀取、修改等問題的實(shí)質(zhì):把指定的數(shù)據(jù)寫到文件流中指定的位置。問題的關(guān)鍵:把文件指針定位到文件流中指定的位置。步驟:定位寫數(shù)據(jù)四、向文件中隨機(jī)地寫入數(shù)據(jù)五、文件定位函數(shù)

fseek(文件指針變量、位移量、起始點(diǎn))注:起始點(diǎn)的取值只有3種:位移量:以起始點(diǎn)為基點(diǎn)移動(dòng)的字節(jié)數(shù)0文件開始處1文件位置指針的當(dāng)前位置2文件尾。文件頭文件尾起始點(diǎn)一位移量十位移量(往后)(往前)位移量應(yīng)為long型

fseek()的返回值:0成功非零失敗例:fseek(fp,20l,0);將位置指針從文件頭移動(dòng)20個(gè)字節(jié)fseek(fp,10l,1);將位置指針移到離文件尾30個(gè)字節(jié)處fseek(fp,30l,2);將位置從當(dāng)前位置向后移10個(gè)字節(jié)六、位置函數(shù)

ftell(文件指針變量);作用:返回位置指針的當(dāng)前指向返回值:≥0,

文件指針的當(dāng)前指向1,

出錯(cuò)例5:文件data1.txt的內(nèi)容如下:Thisisatest.C語言程序設(shè)計(jì),隨機(jī)讀寫函數(shù)測試。要求編寫一程序隨機(jī)讀出指定的記錄。七、重新定位函數(shù)rewind(文件指針變量)作用:使文件指針返回到文件的開頭無返回值例4.(例13.5)#include<stdio.h>

struct

student_type{ charname[10];

intnum;

intage; charsex;}stud[10];main(){inti; FILE*fp;

if((fp=fopen("stud_dat","rb"))==NULL) {printf("cannotopenfile\n"); exit(0);}

for(i=0;i<10;i+=2) {

fseek(fp,i*sizeof(structstudent_type),0);

fread(&stud[i],sizeof(structstudent_type),1,fp);

printf("%s%d%d%c\n",stud[i].name,stud[i].num,stud[i].age,stud[i].sex);}

fclose(fp); }

#include<stdio.h>#include<process.h>#include<string.h>voidmain(){ FILE*fp;

intloc1,loc2; longd=8l; charw;

fp=fopen("data1.txt","r"); if(fp==NULL)

printf("error\n"); else { loc1=fseek(fp,d,0); if(loc1==0) { w=fgetc(fp);

printf("w=%c\n",w); } }運(yùn)行結(jié)果:w=aloc2=9loc2=0

loc2=ftell(fp);

rewind(fp); printf("loc2=%d\n",loc2); loc2=ftell(fp);

fclose(fp); printf("loc2=%d\n",loc2);}?思考:若要采用隨機(jī)讀寫的方式讀取一個(gè)漢字,程序如何修改?提示:一個(gè)漢字占2個(gè)字節(jié)可使用fgets()函數(shù)將要讀出的漢字裝a數(shù)組讀取的字符個(gè)數(shù)必須為≥3的單數(shù)八、文

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(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)論