C語言chap12-文件課件_第1頁
C語言chap12-文件課件_第2頁
C語言chap12-文件課件_第3頁
C語言chap12-文件課件_第4頁
C語言chap12-文件課件_第5頁
已閱讀5頁,還剩35頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

Chap12文件12.1學(xué)生成績文件統(tǒng)計12.2用戶信息加密和校驗12.3文件綜合應(yīng)用:資金賬戶管理本章要點什么是文件?C文件是如何存儲的?什么是文件緩沖系統(tǒng)?工作原理如何?什么是文本文件和二進制文件?怎樣打開、關(guān)閉文件?怎樣編寫文件讀寫程序?怎樣編寫程序,實現(xiàn)簡單的數(shù)據(jù)處理?12.1學(xué)生成績文件統(tǒng)計【例12-1】有5位學(xué)生的計算機等級考試成績被事先保存在數(shù)據(jù)文件C:\f12-1.txt(C盤根目錄下的文件f12-1.txt,需事先準備好該文件)中,包括學(xué)號、姓名和分數(shù),文件內(nèi)容如下:301101Zhangwen91301102Chenhui85301103Wangweidong76301104Zhengwei69301105Guowentao55請讀出文件的所有內(nèi)容顯示到屏幕,并輸出平均分。#include<stdio.h>#include<stdlib.h>#include<process.h>intmain(void){FILE*fp; /*1.定義文件指針*/longnum;charstname[20];inti,score;intavg_score=0;if((fp=fopen("c:\\f12-1.txt","r"))==NULL) /*2.打開文件*/{ printf("Fileopenerror!\n"); exit(0);}

續(xù)下頁….例12-1源程序例12-1源程序/*3.文件處理(逐個讀入和處理數(shù)據(jù))*/for(i=0;i<5;i++){/*從文件讀入成績保存到變量*/

fscanf(fp,"%ld%s%d",&num,stname,&score); avg_score+=score;/*統(tǒng)計總分*//*輸出成績到屏幕*/printf("%ld %s%d\n",num,stname,score);}/*輸出平均分到屏幕*/printf("Averagescore:%d\n",avg_score/5);

if(fclose(fp)){ /*4.關(guān)閉文件*/printf("Cannotclosethefile!\n");exit(0);}return0;}

接上頁……12.1.2文件的概念文件:操作系統(tǒng)中的文件是指駐留在外部介質(zhì)(如磁盤等)中的一個有序數(shù)據(jù)集。各種類型的文件程序文件:源文件、目標程序、可執(zhí)行程序數(shù)據(jù)文件(輸入/輸出):文本文件、圖像文件、聲音文件、可執(zhí)行文件等文件的特點:數(shù)據(jù)永久保存;數(shù)據(jù)長度不定;數(shù)據(jù)按順序存取12.1.3

文本文件和二進制文件

C語言中的文件是數(shù)據(jù)流(由一個個的字節(jié)數(shù)據(jù)組成)文件的兩種數(shù)據(jù)形式:

ASCII碼(文本文件textstream)字符流

二進制碼(二進制文件binarystream)二進制流二進制文件是直接把內(nèi)存數(shù)據(jù)以二進制形式保存。例如,整數(shù)1234文本文件保存:49505152(4個字符)二進制文件保存:04D2(1234的二進制數(shù))字節(jié)

........字節(jié)字節(jié)字節(jié)字節(jié)字節(jié)12.1.4緩沖文件系統(tǒng)內(nèi)存單元內(nèi)存單元數(shù)據(jù)

……緩沖器512字節(jié)……文件由操作系統(tǒng)自動完成程序控制由于磁盤速度慢直接把數(shù)據(jù)寫到磁盤效率很低12.1.4緩沖文件系統(tǒng)向磁盤輸出數(shù)據(jù):數(shù)據(jù)緩沖區(qū),裝滿緩沖區(qū)后磁盤文件。從磁盤讀入數(shù)據(jù):先一次性從磁盤文件將一批數(shù)據(jù)輸入到緩沖區(qū),然后再從緩沖區(qū)逐個讀入數(shù)據(jù)到變量。

數(shù)據(jù)

……緩沖器512字節(jié)……文件由操作系統(tǒng)自動完成程序控制文件名內(nèi)存單元內(nèi)存單元用什么標識緩沖文件與文件類型指針用文件指針指示文件緩沖區(qū)中具體讀寫的位置FILE*fp;數(shù)據(jù)……緩沖器512字節(jié)……文件由操作系統(tǒng)自動完成程序控制fp同時使用多個文件時,每個文件都有緩沖區(qū),用不同的文件指針分別指示。1.文件結(jié)構(gòu)與自定義類型typedefFILE:結(jié)構(gòu)類型,用typedef定義(見stdio.h)typedefstruct{short level; /*緩沖區(qū)使用量*/unsigned flags; /*文件狀態(tài)標志*/char fd; /*文件描述符*/short bsize; /*緩沖區(qū)大小*/unsignedchar *buffer; /*文件緩沖區(qū)的首地址*/unsignedchar *curp; /*指向文件緩沖區(qū)的工作指針*/unsignedchar hold; /*其他信息*/unsigned istemp;short token;}FILE;12.1.5文件結(jié)構(gòu)與文件類型指針

自定義類型(typedef):將C語言中的已有類型(包括已定義過的自定義類型)重新命名新的名稱可以代替已有數(shù)據(jù)類型常用于簡化對復(fù)雜數(shù)據(jù)類型定義的描述typedef<已有類型名><新類型名>;typedef

int

INTEGER; inti,j;<====>INTEGERi,j;typedef

int*

POINT; int*p1;<====>POINTp1;自定義類型(typedef)的使用方法定義變量inti變量名新類型名intINTEGER加上typedef

typedef

intINTEGER用新類型名定義變量INTEGERi;intnum[10]intNUM[10]typedefintNUM[10]NUMa<===>inta[10]2.文件類型指針FILE*fp指向文件緩沖區(qū),通過移動指針實現(xiàn)對文件的操作數(shù)據(jù)……緩沖器512字節(jié)……文件由操作系統(tǒng)自動完成程序控制fp同時使用多個文件時,每個文件都有緩沖區(qū),用不同的文件指針分別指示。如何使fp與具體文件掛鉤?12.1.6文件控制塊FCB文件控制塊FCB(FileControlBlock)OS中對文件的操作控制通過FCB,處理的是FCB列表一個文件對應(yīng)一個FCB文件緩沖區(qū)由程序中fopen語句動態(tài)創(chuàng)建打開文件時,F(xiàn)CB的內(nèi)容信息被復(fù)制到文件緩沖區(qū)保存用文件指針指向文件緩沖區(qū)實現(xiàn)對文件數(shù)據(jù)的訪問12.1.7文件處理步驟四個步驟:①定義文件指針②打開文件:文件指針指向磁盤文件緩沖區(qū)③文件處理:文件讀寫操作④關(guān)閉文件12.2用戶信息加密和校驗【例12-2】為了保障系統(tǒng)安全,通常采取用戶帳號和密碼登錄系統(tǒng)。系統(tǒng)用戶信息存放在一個文件中,系統(tǒng)帳號名和密碼由若干字母與數(shù)字字符構(gòu)成,因安全需要文件中的密碼不能是明文,必須要經(jīng)過加密處理。請編程實現(xiàn):輸入5個用戶信息(包含帳號名和密碼)并寫入文件f12-2.dat。要求文件中每個用戶信息占一行,帳號名和加密過的密碼之間用一個空格分隔。密碼加密算法:對每個字符ASCII碼的低四位求反,高四位保持不變(即將其與15進行異或)。

12.2.1程序解析intmain(void){ FILE*fp;/*1.定義文件指針*/ inti; voidencrypt(char*pwd); structsysusersu; /*2.打開文件,進行寫入操作*/ if((fp=fopen("f12-2.txt","w"))==NULL){ printf("Fileopenerror!\n");exit(0); } for(i=1;i<=5;i++){/*3.將5位用戶帳號信息寫入文件*/printf("Enter%ithsysuser(namepassword):",i);scanf("%s%s",su.username,su.password);/*輸入用戶名和密碼*/encrypt(su.password); /*進行加密處理*/

fprintf(fp,"%s%s\n",su.username,su.password);/*寫入文件*/}if(fclose(fp)){ /*4.關(guān)閉文件*/printf("Cannotclosethefile!\n");exit(0);} return0;}/*加密算法*/voidencrypt(char*pwd){inti;/*與15(二進制碼是00001111)異或,實現(xiàn)低四位取反,高四位保持不變*/for(i=0;i<strlen(pwd);i++)pwd[i]=pwd[i]^15;}#include<stdio.h>#include<string.h>structsysuser{/*用戶帳號信息結(jié)構(gòu)*/ charusername[20]; charpassword[8]; };12.2.2打開文件和關(guān)閉文件if((fp=fopen("f12-2.txt","w"))==NULL){ printf("Fileopenerror!\n");exit(0);}fopen("文件名","文件打開方式")使文件指針與相應(yīng)文件實體對應(yīng)起來程序?qū)ξ募羔樳M行操作,即fp代表磁盤文件函數(shù)fopen()的返回值執(zhí)行成功,則返回包含文件緩沖區(qū)等信息的FILE型地址,賦給文件指針fp不成功,則返回一個NULL(空值)exit(0):關(guān)閉所有打開的文件,并終止程序的執(zhí)行參數(shù)0表示程序正常結(jié)束;非0參數(shù)通常表示不正常的程序結(jié)束文件打開方式fp=fopen("f12-2.txt","w")文件打開方式參數(shù)表文件讀寫與打開方式if讀文件指定的文件必須存在,否則出錯;if寫文件(指定的文件可以存在,也可以不存在)if以"w"方式寫if該文件已經(jīng)存在原文件將被刪去重新建立;

else按指定的名字新建一個文件;

elseif以"a"方式寫if該文件已經(jīng)存在寫入的數(shù)據(jù)將被添加到指定文件原有數(shù)據(jù)的后面,不會刪去原來的內(nèi)容;else

按指定的名字新建一個文件(與“w”相同);if文件同時讀和寫使用"r+"、"w+"或"a+"打開文件關(guān)閉文件if(fclose(fp)){printf("Cannotclosethefile!\n"); exit(0);}fclose(文件指針)把緩沖區(qū)中的數(shù)據(jù)寫入磁盤扇區(qū),確保寫文件的正常完成釋放文件緩沖區(qū)單元和FILE結(jié)構(gòu)體,使文件指針與具體文件脫鉤。函數(shù)fclose()的返回值返回0:正常關(guān)閉文件返回非0:無法正常關(guān)閉文件12.2.3文件讀寫【例12-3】復(fù)制用戶文件。將例12-2的用戶信息文件f12-2.txt文件備份一份,取名為文件f12-3.txt。說明:運行程序前請將文件f12-2.txt與源程序放在同一目錄下。例12-3源程序#include<stdio.h>intmain(void){ FILE*fp1,*fp2; charch;if((fp1=fopen("f12-2.txt","r"))==NULL){printf("Fileopenerror!\n");exit(0); } if((fp2=fopen("f12-3.txt","w"))==NULL){ printf("Fileopenerror!\n"); exit(0); }

while(!feof(fp1)){ch=fgetc(fp1);if(ch!=EOF)fputc(ch,fp2); }/*關(guān)閉文件f12-2.txt*/if(fclose(fp1)){printf("Cannotclosethefile!\n");exit(0);}/*關(guān)閉文件f12-3.txt*/if(fclose(fp2)){printf("Cannotclosethefile!\n");exit(0);}return0;}

打開多個文件if((fp1=fopen("f12-2.txt","r"))==NULL){printf("Fileopenerror!\n");exit(0);}if((fp2=fopen("f12-3.txt","w"))==NULL){printf("Fileopenerror!\n"); exit(0);}C語言允許同時打開多個文件不同的文件對應(yīng)不同的文件指針不允許同一個文件在關(guān)閉前再次打開文件讀寫函數(shù)字符讀寫函數(shù):fgetc()/fputc()字符串讀寫函數(shù):fputs()

/fgets()格式化讀寫函數(shù):fscanf()

/fprintf()二進制讀寫函數(shù):fread()/fwrite()其他相關(guān)函數(shù):檢測文件結(jié)尾函數(shù)feof()檢測文件讀寫出錯函數(shù)ferror()清除末尾標志和出錯標志函數(shù)clearerr()文件定位的函數(shù)fseek()、rewind()、ftell()1.字符讀寫函數(shù)fgetc和fputc函數(shù)fputc()fputc(ch,fp);把一個字符ch寫到fp所指示的磁盤文件上返回值-1(EOF):寫文件失敗ch:寫文件成功函數(shù)fgetc()ch=fgetc(fp);從fp所指示的磁盤文件上讀入一個字符到ch區(qū)分鍵盤字符輸入函數(shù)getchar()while(!feof(fp1)){ch=fgetc(fp1);if(ch!=EOF)fputc(c,fp2);}2.字符串方式讀寫函數(shù)fgets和fputs函數(shù)fputs()

fputs(s,fp);用來向指定的文本文件寫入一個字符串s:要寫入的字符串,結(jié)束符’\0’不寫入文件。函數(shù)返回值執(zhí)行成功,函數(shù)返回所寫的最后一個字符否則,函數(shù)返回EOF字符串方式讀寫函數(shù)fgets和fputs函數(shù)fgets()fgets(s,n,fp);從文本文件中讀取字符串

s:可以是字符數(shù)組名或字符指針;n:指定讀入的字符個數(shù);fp:文件指針函數(shù)被調(diào)用時,最多讀取n-1個字符,并將讀入的字符串存入s所指向內(nèi)存地址開始的n-1個連續(xù)的內(nèi)存單元中。當函數(shù)讀取的字符達到指定的個數(shù),或接收到換行符,或接收到文件結(jié)束標志EOF時,將在讀取的字符后面自動添加一個’\0’字符;若有換行符,則將換行符保留(換行符在’\0’字符之前);若有EOF,則不保留函數(shù)返回值執(zhí)行成功,返回讀取的字符串;如果失敗,則返回空指針,這時,s的內(nèi)容不確定例12-2的f12-2.txt文件保存著系統(tǒng)用戶信息,編寫一個函數(shù)checkUserValid()用于登錄系統(tǒng)時校驗用戶的合法性。檢查方法是:在程序運行時輸入用戶名和密碼,然后在用戶文件中查找該用戶信息,如果用戶名和密碼在文件中找到,則表示用戶合法,返回1,否則返回0。程序運行時,輸入一個用戶名和密碼,調(diào)用checkUserValid()函數(shù),如果返回1,則提示“Validuser!”,否則輸出“Invaliduser!”。例12-4提示:合法性檢查的規(guī)則。由于文件中的用戶名和密碼按行存取,把一行看作整體得字符串s1,將輸入的用戶名和密碼加密后生成另一個字符串s2,然后通過比較s1和s2,來確定文件中是否存在用戶。例12-4源程序/*校驗用戶信息的合法性,成功返回1,否則返回0*/intcheckUserValid(structsysuser*psu){FILE*fp;charusr[30],usr1[30],pwd[10];intcheck=0;/*檢查結(jié)果變量,初始化為0*//*連接生成待校驗字符串*/strcpy(usr,psu->username);/*復(fù)制psu->username到usr1*/strcpy(pwd,psu->password);/*復(fù)制psu->password到pwd*/encrypt(pwd);/*調(diào)用例12-2的encrypt對密碼進行加密*//*連接usr、空格、pwd和\n構(gòu)成新字符串usr,用于在文件中逐行檢查*/

strcat(usr,"");strcat(usr,pwd);strcat(usr,"\n");

/*打開文件"f12-2.txt"讀入*/if((fp=fopen("f12-2.txt","r"))==NULL){printf("Fileopenerror!\n");exit(0);}/*從文件讀入用戶信息數(shù)據(jù),遍歷判斷是否存在*/while(!feof(fp)){

fgets(usr1,30,fp);/*讀入一行用戶信息作為一個字符串到usr1*/if(strcmp(usr,usr1)==0){/*比較判斷usr與usr1是否相同*/check=1;break;}}if(fclose(fp)){printf("Cannotclosethefile!\n");exit(0);}/*關(guān)閉文件*/returncheck;}3.格式化文件讀寫fscanf和fprintffscanf(文件指針,格式字符串,輸入表);fprintf(文件指針,格式字符串,輸出表);指定格式的輸入輸出函數(shù)FILE*fp;intn;floatx;fp=fopen("a.txt","r");fscanf(fp,"%d%f",&n,&x);表示從文件a.txt分別讀入整型數(shù)到變量n、浮點數(shù)到變量x

fp=fopen("b.txt","w"); fprintf(fp,"%d%f",n,x);表示把變量n和x的數(shù)值寫入文件b.txt4.數(shù)據(jù)塊讀寫fread()和fwrite()fread(buffer,size,count,fp);從二進制文件中讀入一個數(shù)據(jù)塊到變量fwrite(buffer,size,count,fp);向二進制文件中寫入一個數(shù)據(jù)塊 buffer:指針,表示存放數(shù)據(jù)的首地址;size:數(shù)據(jù)塊的字節(jié)數(shù)count:要讀寫的數(shù)據(jù)塊塊數(shù)fp:文件指針12.2.4其他相關(guān)函數(shù)函數(shù)feof()feof(fp);判斷fp指針是否已經(jīng)到文件末尾,函數(shù)返回值1:到文件結(jié)束位置0:文件未結(jié)束函數(shù)rewind()rewind(FILE*fp);定位文件指針,使文件指針指向讀寫文件的首地址,即打開文件時文件指針所指向的位置。其他相關(guān)函數(shù)函數(shù)fseek()——用來控制指針移動fseek(fp,offset,from);offset:移動偏移量,long型from:起始位置,文件首部、當前位置和文件尾部分別對應(yīng)0,1,2,或常量SEEK_SET、SEEK_CUR、SEEK_END。例如:fseek(fp,20L,0):將文件位置指針移動到離文件首20字節(jié)處fseek(fp,-20L,SEEK_END):將文件位置指針移動到離文件尾部前20字節(jié)處函數(shù)ftell()ftell(文件指針);獲取當前文件指針的位置,即相對于文件開頭的位移量(字節(jié)數(shù))函數(shù)出錯時,返回-1L其他相關(guān)函數(shù)fer

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論