C語言程序設計-基于計算思維的培養(yǎng) 課件 第12章 文件_第1頁
C語言程序設計-基于計算思維的培養(yǎng) 課件 第12章 文件_第2頁
C語言程序設計-基于計算思維的培養(yǎng) 課件 第12章 文件_第3頁
C語言程序設計-基于計算思維的培養(yǎng) 課件 第12章 文件_第4頁
C語言程序設計-基于計算思維的培養(yǎng) 課件 第12章 文件_第5頁
已閱讀5頁,還剩35頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第十二章文件12.1文件的概念12.2文件的打開與關閉12.3順序讀寫數(shù)據(jù)文件12.4隨機讀寫數(shù)據(jù)文件12.5文件讀寫的出錯檢測目錄文件概念存儲在外部介質(zhì)上的具有名字的一組相關數(shù)據(jù)的集合數(shù)據(jù)一般以文件的形式為用戶、應用程序使用文件的好處:程序與數(shù)據(jù)分離、數(shù)據(jù)共享、長期保存文件的組織:通過建立目錄/文件夾目錄中保存文件(同一目錄中文件不能同名)使用者只要知道文件的路徑及文件名,就能使用文件文件分類根據(jù)數(shù)據(jù)的組織形式,數(shù)據(jù)文件可分為ASCII文件和二進制文件。數(shù)據(jù)在內(nèi)存中是以二進制形式存儲的,如果不加轉(zhuǎn)換地輸出到外存,就是二進制文件。二進制文件存儲的字節(jié)不一定表示字符,無需ASCII碼表進行字符變換,讀寫速度快必須按照文件存儲的類型和格式讀出才能恢復其本來面貌ASCII文件又稱文本文件,每一個字節(jié)放一個字符的ASCII代碼圖12-1變量a在內(nèi)存中占4個字節(jié)圖12-2變量a在二進制文件中占4個字節(jié)圖12-3變量a在文本文件中占5個字節(jié)inta=10001;文件指針緩沖文件系統(tǒng)中,關鍵的概念是“文件指針”,與文件相關聯(lián)的每個流都有一個FILE類型的結構體聲明FILE結構體類型的信息包含在頭文件“stdio.h”中一般設置一個指向FILE類型變量的指針變量,然后通過它來引用這些FILE類型變量typedef

struct{

shortlevel;/*緩沖區(qū)‘滿’或‘空’的程度*/

unsignedflags;/*文件狀態(tài)標志*/

charfd;/*文件描述符*/

unsignedcharhold;/*如無緩沖區(qū)不讀字符*/

shortbsize;/*緩沖區(qū)的大小*/

unsignedchar*buffer;/*數(shù)據(jù)緩沖區(qū)的位置*/

unsignedchar*curp;/*指針當前的指向*/

unsignedistemp;/*臨時文件指示器*/

shorttoken;/*用于有效性檢查*/}FILE;/*在stdio.h文件中定義*/文件指針FILE

*fp1,*fp2,*fp3;文件f1的文件信息區(qū)fp1文件f2的文件信息區(qū)fp2文件f3的文件信息區(qū)fp3FILE*fopen(constchar*filename,constchar*mode);例文件打開與測試

FILE*fp;fp=fopen("in.txt","w");if(NULL==fp){printf("Fileopenerror!\n");exit(0);}例FILE*fp;fp=fopen("d:\\stu_dat.txt","r");例FILE*fp;char*filename="d:\\stu_dat.txt";fp=fopen(filename,"r");文件使用方式:

r為讀打開文件

w為寫打開文件

a為追加打開文件文件打開文件關閉關閉文件用fclose函數(shù)。fclose函數(shù)調(diào)用的一般形式為:fclose(文件指針);

例如:

fclose(fp);如果不關閉文件將會丟失數(shù)據(jù)。按字符讀寫文件函數(shù)名調(diào)用形式功能返回值fgetcgetcch=fgetc(fp)ch=getc(fp)從fp指向的文件讀入一個字符讀成功,帶回所讀的字符,失敗則返回文件結束標志EOF(即-1)getcharch=getchar()從標準輸入流stdin(默認鍵盤)讀入一個字符讀成功,帶回所讀的字符,失敗則返回文件結束標志EOF(即-1)fputcputcfputc(ch,fp)putc(ch,fp)把字符ch寫到文件指針變量fp所指向的文件中寫成功,返回值就是輸出的字符;輸出失敗,則返回EOF(即-1)putcharputchar(ch)向標準輸出流stdout(默認屏幕)寫一個字符寫成功,返回值就是輸出的字符;輸出失敗,則返回EOF(即-1)讀寫一個字符的函數(shù)#definegetchar(ch)getc(stdin)#defineputchar(ch)putc(ch,stdout)fputc(ch,stdout)相當于putchar(ch)fgetc(stdin)相當于getchar()【例12.1】

從鍵盤輸入一些字符,然后把它們保存到磁盤文件中。#include<stdio.h>#include<stdlib.h>intmain(){ FILE*fp; charch,filename[20]; printf("Pleaseinputfilename:"); scanf("%s",filename); if((fp=fopen(filename,"w"))==NULL) { printf("cannotopenthisfile!\n"); exit(0); } ch=getchar();//用來接收最后輸入的回車符 printf("Pleaseinputastring:"); ch=getchar();//接收從鍵盤輸入的第一個字符 while(ch!='\n') { fputc(ch,fp); ch=getchar(); } fclose(fp); return0; }為什么要判斷文件打開是否成功呢?fp=fopen(filename,“w”);if((fp==NULL){printf("cannotopenthisfile!\n");exit(0); }按字符讀寫文件【例12.2】

編寫程序,將0~127之間的ASCII碼對應的字符寫到文件中,然后從文件中讀出并顯示在屏幕上。#include<stdio.h>#include<stdlib.h>intmain(){ FILE*fp; charch; inti; if((fp=fopen("data.dat","wb"))==NULL){ printf("Failedtoopenthisfile!\n"); exit(0); } for(i=0;i<128;i++){ fputc(i,fp); } fclose(fp); if((fp=fopen("data.dat","rb"))==NULL){ printf("Failedtoopenthisfile!\n"); exit(0); } while((ch=fgetc(fp))!=EOF){ putchar(ch); } fclose(fp); return0;}函數(shù)feof()檢查是否到達文件尾,當文件位置指針指向文件尾時,返回非0值,否則返回0值ch=fgetc(fp);while(!feof(fp)){putchar(ch);ch=fgetc(fp);}按字符讀寫文件函數(shù)ferror()檢查讀取是否出錯,出錯,返回非0值,否則返回0值if(ferror(fp)){printf(“Erroronfile.\n”);}問題:讀到文件尾或讀取出錯時,fgetc()都返回EOF,如何區(qū)分二者?#include<stdio.h>#include<stdlib.h>intmain(){ FILE*fp; charch; inti; if((fp=fopen("data.dat","wb"))==NULL){ printf("Failedtoopenthisfile!\n"); exit(0); } for(i=0;i<128;i++){ fputc(i,fp); } fclose(fp); if((fp=fopen("data.dat","rb"))==NULL){ printf("Failedtoopenthisfile!\n"); exit(0); } while((ch=fgetc(fp))!=EOF){ putchar(ch); } fclose(fp); return0;}while((ch=fgetc(fp))!=EOF){if(isprint(ch)){printf(“%c\t”,ch);}else{printf(“%d\t”,ch);}}按字符讀寫文件讀寫一個字符串的函數(shù)函數(shù)名調(diào)用形式功能返回值fgetsfgets(str,n,fp)從fp指向的文件讀入長度為(n-1)的字符串,存放到字符數(shù)組str中,保留’\n’讀成功,返回地址str,失敗則返回NULL)fputsfputs(str,fp)str所指向的字符串寫到文件指針變量fp所指向的文件中,不添加’\n’寫成功,返回0;否則返回非0值按行讀寫文件函數(shù)名調(diào)用形式功能返回值getsgets(str)從標準輸入流stdin讀入字符串,存放到字符數(shù)組str中,不保留’\n’,替換為’\0’讀成功,返回地址str,失敗則返回NULL)putsputs(str)將字符串str寫到標準輸出流stdout,并在其后添加一個換行符寫成功,返回0;否則返回非0值【例12.4】

從鍵盤讀入若干字符串,對它們按字母大小的順序排序,然后把排好序的字符串存入磁盤文件中。#include<stdio.h>#include<string.h>#include<stdlib.h>#defineM10#defineN30intmain(){FILE*fp;charstr[M][N],temp[N];inti,j,k,n;printf("Pleaseinputthenumberofstrings:");scanf("%d",&n);printf("Pleaseinputseveralstrings:\n");getchar(); /*清空緩沖區(qū)*/ for(i=0;i<n;i++){fgets(str[i],sizeof(str[i]),stdin); /*也可調(diào)用gets(str[i])*/}for(i=0;i<n-1;i++){ /*字符串選擇排序*/k=i;for(j=i+1;j<n;j++){if(strcmp(str[k],str[j])>0)k=j;}if(k!=i){strcpy(temp,str[i]);strcpy(str[i],str[k]);strcpy(str[k],temp);}}if((fp=fopen("D:\\string.txt","w"))==NULL){printf("cannotopenthisfile\n");exit(0);}for(i=0;i<n;i++){fputs(str[i],fp);/*將字符串寫入文件中*/}fclose(fp);if((fp=fopen("D:\\string.txt","r"))==NULL){printf("cannotopenthisfile\n");exit(0);}printf("\nAftersortedsequenceis:\n");for(i=0;i<n;i++){fgets(str[i],sizeof(str[i]),fp);/*從文件中讀取字符串*/puts(str[i]);/*把讀取的字符串顯示在屏幕上*/}fclose(fp);return0; }按行讀寫文件格式化讀寫文件#include<stdio.h>main(){FILE*fp;fp=fopen(“point.txt”,”r");printf(“x\ty\n”);while(!feof(fp)){fscanf(fp,”%lf%lf”,&x,&y);printf(“%lf%lf\n”,x,y);}fclose(fp);}【例12.5】顯示文件中的數(shù)據(jù)◆fscanf函數(shù)讀取文本文件;◆格式:fscanf(文件指針,格式字符串,變量地址列表);◆作用:從文本文件中讀取數(shù)據(jù);fscanf(fp,”%d%d”,&a,&b);◆fscanf(stdin,”%d”,&a)與scanf(“%d”,&a)等價;◆feof函數(shù)測試數(shù)據(jù)是否讀完,即是否讀到文件尾;◆當以”r”方式打開文件時,文件位置指示器指向文件第一個數(shù)據(jù),隨著數(shù)據(jù)的讀取,位置指示器向后移動;◆當文件位置指示器指向文件結束符時,feof函數(shù)的值非0,否則,feof函數(shù)的值為0;◆fclose函數(shù)關閉文件。所謂“關閉”是指撤銷文件信息區(qū)和文件緩沖區(qū)。fclose(fp);格式化讀寫文件doubledistance(doublex,doubley,doublex0,doubley0){doubledis;dis=sqrt((x-x0)*((x-x0)+((y-y0)*((y-y0));returndis;}#include<stdio.h>voidmain(){FILE*fp;fp=fopen(“point.txt”,”r");printf(“x\ty\n”);while(!feof(fp)){fscanf(fp,”%lf%lf”,&x,&y);printf(“%lf\t%lf\t%lf\n”,x,y,distance(x,y,0,0));}fclose(fp);}【例12.6】計算距離◆fprintf函數(shù)將數(shù)據(jù)寫入文本文件;◆格式:fprintf(文件指針,格式字符串,輸出列表);◆作用:按指定格式向文本文件寫入數(shù)據(jù);fprintf函數(shù)與printf函數(shù)作用相仿;fprintf(fp,”%d,%6.2f”,a,b);◆fprintf(stdout,”hello,world!”)與printf(“hello,world!”)等價.格式化讀寫文件#include<stdio.h>voidmain(){FILE*fp1;fp1=fopen(“point.txt”,”r");fp2=fopen(“dis.txt”,”w");printf(“x\ty\n”);while(!feof(fp1)){fscanf(fp1,”%lf%lf”,&x,&y);fprintf(fp2,“%lf\t%lf\t%lf\n”,x,y,distance(x,y,0,0));}fclose(fp1);fclose(fp2);}#include<stdio.h>voidmain(){FILE*fp;doublex,y,dis;fp=fopen(“dis.txt”,”r");printf(“x\ty\n”);while(!feof(fp)){fscanf(fp,”%lf%lf%lf”,&x,&y,&dis);printf(“%lf\t%lf\t%lf\n”,x,y,dis);}fclose(fp);}【例12.7】將數(shù)據(jù)寫入文件格式化讀寫文件【例12.8】

編寫程序,從鍵盤輸入5個學生的具體信息(學號、姓名、性別、出生日期、地址)及4門課的成績,計算每個學生4門課的平均分,并將學生的具體信息和各門課成績及平均分保存到文件score.txt中。typedefstructdate{ intmonth; intday; intyear;}DATE;typedefstructstudent{ longid; charname[20]; charsex; DATEbirthday; charaddr[30]; floatscore[4]; floataver;}STUDENT;格式化讀寫文件voidGetScore(STUDENTstu[],intm,intn);voidComputeAverage(STUDENTstu[],intm,intn);voidSavetoFile(STUDENTstu[],intm,intn);intmain(){ STUDENTstu[N]; intm; printf("Inputthenumberofstudents:"); scanf("%d",&m); GetScore(stu,m,4); ComputeAverage(stu,m,4); SavetoFile(stu,m,4); return0;}voidGetScore(STUDENTstu[],intm,intn){inti,j;for(i=0;i<m;i++){ printf("Inputrecord%d:\n",i+1); scanf("%ld",&stu[i].id); scanf("%s",stu[i].name); scanf("%c",&stu[i].sex); scanf("%d",&stu[i].birthday.month); scanf("%d",&stu[i].birthday.day); scanf("%d",&stu[i].birthday.year); scanf("%s",stu[i].addr); for(j=0;j<n;j++) { scanf("%f",&stu[i].score[j]); }}}格式化讀寫文件/*函數(shù)功能:計算m個學生n門課的平均分,存入數(shù)組的成員aver中*/voidComputeAverage(STUDENTstu[],intm,intn){ inti,j; floatsum; for(i=0;i<m;i++) { sum=0.0; for(j=0;j<n;j++) { sum=sum+stu[i].score[j]; } stu[i].aver=sum/n; }}voidSavetoFile(STUDENTstu[],intm,intn){FILE*fp;inti,j;if((fp=fopen("score.txt","w"))==NULL){printf("Failedtoopenthisfile!\n");exit(0);}fprintf(fp,"%d\t%d\n",m,n);for(i=0;i<m;i++){fprintf(fp,"%10ld%8s%3c%02d%02d%6d%8s",stu[i].id,stu[i].name,stu[i].sex,stu[i].birthday.month,stu[i].birthday.day,stu[i].birthday.year,stu[i].addr);for(j=0;j<n;j++){fprintf(fp,"%5.1f",stu[i].score[j]);}fprintf(fp,"%5.1f\n",stu[i].aver);}fclose(fp);}格式化讀寫文件【例12.9】

從例12.8生成的文件score.txt中讀取每個學生的學號、姓名、性別、出生日期、地址、各門課的成績及平均分,并顯示在屏幕上。typedefstructdate{

…/*同前,略*/}DATE;typedefstructstudent{

…/*同前,略*/}STUDENT;voidPrintScore(STUDENTstu[],intm,intn);voidReadfromFile(STUDENTstu[],int*m,int*n);intmain(){ STUDENTstu[N]; intm,n=4; ReadfromFile(stu,&m,&n); PrintScore(stu,m,n); return0;}voidReadfromFile(STUDENTstu[],int*m,int*n){FILE*fp;inti,j;if((fp=fopen("score.txt","r"))==NULL){printf("Failedtoopenthisfile!\n");exit(0);}fscanf(fp,"%d\t%d",m,n);for(i=0;i<*m;i++){fscanf(fp,"%10ld",&stu[i].id);fscanf(fp,"%8s",stu[i].name);fscanf(fp,"%c",&stu[i].sex);fscanf(fp,"%2d",&stu[i].birthday.month);fscanf(fp,"%2d",&stu[i].birthday.day);fscanf(fp,"%6d",&stu[i].birthday.year);fscanf(fp,"%8s",stu[i].addr); for(j=0;j<*n;j++){ fscanf(fp,"%5f",&stu[i].score[j]);}fscanf(fp,"%5f",&stu[i].aver);}fclose(fp);}格式化讀寫文件voidPrintScore(STUDENTstu[],intm,intn){inti,j;for(i=0;i<m;i++){printf("%10ld%8s%3c%02d%02d%6d%8s",stu[i].id,stu[i].name,stu[i].sex,stu[i].birthday.month,stu[i].birthday.day,stu[i].birthday.year,stu[i].addr);for(j=0;j<n;j++){printf("%5.1f",stu[i].score[j]);} printf("%5.1f\n",stu[i].aver);}}問題的提出:如何讀寫二進制文件◆fread與fwrite的函數(shù)原型:size_tfread(void*buffer,size_tsize,size_tcount,FILE*fp)size_tfwrite(void*buffer,size_tsize,size_tcount,FILE*fp)功能:讀/寫數(shù)據(jù)塊返值:成功,返回讀/寫的塊數(shù);出錯或文件尾,返回0typedefunsignedsize_t;buffer:指向要輸入/輸出數(shù)據(jù)塊的首地址的指針size:每個要讀/寫的數(shù)據(jù)塊的大小(字節(jié)數(shù))count:要讀/寫的數(shù)據(jù)塊的個數(shù)fp:要讀/寫的文件指針fread與fwrite一般用于二進制文件的輸入/輸出實例例floatf[2];FILE*fp;fp=fopen(“aa.dat”,“rb”);

fread(f,4,2,fp);for(i=0;i<2;i++)

fread(&f[i],4,1,fp);例structstudent{intnum;charname[20];charsex;intage;floatscore[3];}stud[10];for(i=0;i<10;i++)

fread(&stud[i],sizeof(structstudent),1,fp);#include<stdio.h>#defineSIZE2structstudent_type{charname[10];intnum;intage;charaddr[15];}stud[SIZE];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();display();}【例12.10】鍵盤輸入2個學生數(shù)據(jù),保存在文件中,并重新讀取并顯示voidsave(){FILE*fp;inti;if((fp=fopen("d:\\stu_dat","w"))==NULL){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);}voiddisplay(){FILE*fp;inti;if((fp=fopen("d:\\stu_dat","r"))==NULL){printf("cannotopenfile\n"); return;}for(i=0;i<SIZE;i++){fread(&stud[i],sizeof(structstudent_type),1,fp);printf("%-10s%4d%4d%-15s\n",stud[i].name,stud[i].num,stud[i].age,stud[i].addr);}

fclose(fp);}如何隨機存取二進制文件有時需要訪問文件的特定部分而不訪問其它部分rewind函數(shù)函數(shù)原型:voidrewind(FILE*fp)功能:重置文件位置指針到文件開頭返值:無fseek函數(shù)函數(shù)原型:intfseek(FILE*fp,longoffset,intwhence)功能:改變文件位置指針的位置返值:成功,返回0;失敗,返回非0值起始點文件開始

SEEK_SET0文件當前位置

SEEK_CUR1文件末尾

SEEK_END2例fseek(fp,100L,0);fseek(fp,50L,1);fseek(fp,-10L,2);ftell函數(shù)函數(shù)原型:longftell(FILE*fp)功能:返回位置指針當前位置(用相對文件開頭的位移量表示)返值:成功,返回當前位置指針位置;失敗,返回-1L,例磁盤文件上有3個學生數(shù)據(jù),要求讀入第1,3學生數(shù)據(jù)并顯示如何隨機存取二進制文件main(){inti;FILE*fp;if((fp=fopen(“d:\\stu_dat","r"))==NULL){printf("can'topenfile\n");exit(0);}for(i=0;i<3;i+=2){fseek(fp,i*sizeof(structstudent_type),0);fread(&stud[i],sizeof(structstudent_type),1,fp);printf("%s%d%d%s\n",stud[i].name,stud[i].num,stud[i].age,stud[i].addr);}f

溫馨提示

  • 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論