C語言程序設(shè)計課件:文件_第1頁
C語言程序設(shè)計課件:文件_第2頁
C語言程序設(shè)計課件:文件_第3頁
C語言程序設(shè)計課件:文件_第4頁
C語言程序設(shè)計課件:文件_第5頁
已閱讀5頁,還剩48頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

文件第一節(jié)文件的基本概念與分類第二節(jié)打開和關(guān)閉文件第三節(jié)文件的順序讀寫第四節(jié)隨機文件的讀寫第五節(jié)項目任務:項目案例綜合實現(xiàn)第一節(jié)文件的基本概念與分類文件是程序設(shè)計中一個重要的概念。所謂“文件”一般指存儲在外部介質(zhì)(如磁盤等)上的一組相關(guān)數(shù)據(jù)的有序集合。這個數(shù)據(jù)集有一個名稱,叫做文件名。實際上在前面的各章中我們已經(jīng)多次使用了文件,例如源程序文件、目標文件、可執(zhí)行文件、庫文件(頭文件)等。操作系統(tǒng)是以文件為單位對數(shù)據(jù)進行管理的,也就是說,如果想找到存儲在外部介質(zhì)上的數(shù)據(jù),必須先按文件名找到所指定的文件,然后再從該文件中讀取數(shù)據(jù)。向外部介質(zhì)上存儲數(shù)據(jù)也必須先建立一個文件,才能向它輸出(寫)數(shù)據(jù)。從文件數(shù)據(jù)的組織形式即數(shù)據(jù)在磁盤上的存儲形式看,C語言的文件可分為ASCII文件和二進制文件。ASCII文件:又稱為文本文件(text)文件,特點是數(shù)據(jù)在外部介質(zhì)中存放時一個字節(jié)存放一個ASCII碼字符。例如:整數(shù)1024的ASCII碼存儲形式為:上面可以看出,以ASCII形式存放需要占用4個字節(jié)。二進制文件:將內(nèi)存中的數(shù)據(jù)存入磁盤的時候不需要進行數(shù)據(jù)轉(zhuǎn)換,在內(nèi)存中的數(shù)據(jù)形式與輸出到外部文件中的數(shù)據(jù)形式完全一致。int型的1024若按二進制輸出則占用2個字節(jié)。例如:整數(shù)1024的二進制存儲形式為:001100010011000000110010001101000000010000000000從上面可以看出,在ASCII文件中采用ASCII碼的形式保存數(shù)據(jù),每個字符都是以ASCII碼形式存儲,方便了對字符的逐個處理,在操作系統(tǒng)下也可以直接識別,但占用的磁盤存儲空間較多,同時還要付出由二進制形式向ASCII碼轉(zhuǎn)換的時間開銷。用二進制形式存儲可以節(jié)省磁盤空間和轉(zhuǎn)換時間,但輸出的形式由于是內(nèi)存中的表示形式,所以一般不能直接識別。因此,一般中間數(shù)據(jù)用二進制文件保存,輸入輸出使用ASCII文件。從用戶使用的觀點看,文件可分為普通文件和設(shè)備文件。普通文件是指駐留在磁盤或其它外部介質(zhì)上的一個有序數(shù)據(jù)集,可以是源文件、目標文件、可執(zhí)行程序;也可以是一組待輸入處理的原始數(shù)據(jù),或者是一組輸出的結(jié)果。設(shè)備文件是指與主機相聯(lián)的各種外部設(shè)備,如顯示器、打印機、鍵盤等。例如將鍵盤看作是輸入文件,將顯示器和打印機看作是輸出文件。在C語言中,對外部設(shè)備的輸入輸出處理過程就是讀寫設(shè)備文件的過程。例如:將打印機作為設(shè)備文件時,可使用由系統(tǒng)命名的PRN文件(即打印機文件)直接輸出,所有向PRN文件傳送信息的操作就是向打印機輸出打印信息。通常把顯示器定義為標準輸出文件,一般情況下在屏幕上顯示有關(guān)信息就是向標準輸出文件輸出。如前面經(jīng)常使用的printf,putchar函數(shù)就是這類輸出。鍵盤通常被指定為標準的輸入文件,從鍵盤上輸入就意味著從標準輸入文件上輸入數(shù)據(jù)。scanf,getchar函數(shù)就屬于這類輸入。因此,C語言中可將普通文件和設(shè)備文件統(tǒng)一作為邏輯文件來看待并采用相同的操作方法,從而大大地方便了程序設(shè)計。從C語言處理文件的方法看可以將文件分為“緩沖文件系統(tǒng)”和“非緩沖文件系統(tǒng)”兩類。緩沖文件系統(tǒng)是指對每個正在使用的文件,系統(tǒng)自動地在內(nèi)存區(qū)開辟一個緩沖區(qū)。從內(nèi)存向磁盤輸出數(shù)據(jù)必須先送到內(nèi)存中的緩沖區(qū),裝滿緩沖區(qū)后才一起送到磁盤。如果從磁盤向內(nèi)存讀入數(shù)據(jù),則從磁盤文件中先將一批數(shù)據(jù)輸入到內(nèi)存緩沖區(qū),然后再從緩沖區(qū)逐個地將數(shù)據(jù)送到程序數(shù)據(jù)區(qū)。ANSIC只采用緩沖文件系統(tǒng)。非緩沖文件系統(tǒng)是指系統(tǒng)不自動開辟確定大小的緩沖區(qū),而是由程序為每一個文件設(shè)定確定大小的緩沖區(qū),它占用的是操作系統(tǒng)的緩沖區(qū),而不是用戶存儲區(qū)。第二節(jié)打開和關(guān)閉文件程序中要實現(xiàn)對文件的處理,先必須在內(nèi)部文件與外部文件之間建立聯(lián)系,打開文件,所謂打開文件,實際上是建立文件的各種有關(guān)信息,并使文件指針指向該文件,然后才可對文件進行操作。文件最基本的操作是讀寫操作,操作完成后應當切斷內(nèi)部文件與外部文件之間的聯(lián)系,關(guān)閉文件,也就是要斷開文件指針與文件之間的聯(lián)系。對文件進行的所有操作通過C編譯系統(tǒng)提供的標準函數(shù)完成,這些函數(shù)的信息包含在頭文件“stdio.h”中。一、文件指針要調(diào)用一個文件,需要以下信息:(1)文件當前的讀寫位置,該位置指文件存放在哪個磁介質(zhì)中。(2)與該文件對應的內(nèi)存緩沖區(qū)的地址,緩沖區(qū)的地址一般由系統(tǒng)自動提供。(3)緩沖區(qū)中未被處理的字符數(shù),即是否有數(shù)據(jù)未被處理。(4)文件操作方法,指讀數(shù)據(jù)還是寫數(shù)據(jù)。緩沖區(qū)為每一個文件開辟一個“文件信息區(qū)”用來存放以上這些信息,這個信息區(qū)在內(nèi)存中,是一個結(jié)構(gòu)體變量。只要程序用到一個文件,系統(tǒng)就要為此文件開辟一個這樣的一個結(jié)構(gòu)體變量。有幾個文件,就開辟幾個這樣的一個結(jié)構(gòu)體變量,分別用來存放各個文件的有關(guān)信息。這些結(jié)構(gòu)體變量不用變量名來標識,而是設(shè)置一個指向該結(jié)構(gòu)體變量的指針變量,通過它來訪問該結(jié)構(gòu)體變量。因此,在C語言中用一個指針變量指向一個文件,這個指針稱為文件指針。通過文件指針就可對它所指的文件進行各種操作。定義說明文件指針的一般形式為:FILE*指針變量標識符;其中FILE應為大寫,它實際上是由系統(tǒng)定義的一個結(jié)構(gòu),該結(jié)構(gòu)中含有文件名、文件狀態(tài)和文件當前位置等信息。在編寫源程序時不必關(guān)心FILE結(jié)構(gòu)的細節(jié)。例如:FILE*fp;表示fp是指向FILE結(jié)構(gòu)的指針變量,通過fp即可找存放某個文件信息的結(jié)構(gòu)變量,然后按結(jié)構(gòu)變量提供的信息找到該文件,實施對文件的操作。習慣上也籠統(tǒng)地把fp稱為指向一個文件的指針。二、文件的打開(fopen()函數(shù))所謂“打開”,是指在程序和操作系統(tǒng)之間建立起聯(lián)系,程序把所要操作的文件的一些信息通知給操作系統(tǒng)。這些信息中除包括文件名外,還要指出讀寫方式及讀寫位置。如果是讀,則需要先確認此文件是否已存在;如果是寫,則檢查原來是否有同名文件,如有則將該文件刪除,然后新建立一個文件,并將讀寫位置設(shè)定于文件開頭,準備寫入數(shù)據(jù)。fopen函數(shù)用來打開一個文件,其調(diào)用的一般形式為:FILE*fp;fp=fopen(文件名,使用文件方式);其中,fp是文件指針名,“文件指針名”必須是被說明為FILE類型的指針變量,“文件名”是被打開文件的文件名?!笆褂梦募绞健笔侵肝募念愋秃筒僮饕蟆@纾篎ILE*fp;fp=fopen(“file1”,”r”);其意義是在當前目錄下打開文件file1,并且以“讀”方式打開,同時返回指向該文件的指針并賦給fp。又如:FILE*fp1;fp1=("d:\\file2',"w");其意義是打開D驅(qū)動器磁盤的根目錄下的文件file2,并且以“寫”方式打開。兩個反斜線“\\”中的第一個表示轉(zhuǎn)義字符,第二個表示根目錄。使用文件的方式共有12種,下表就是它們的符號和含義。表9-1文件使用方式表說明:(1)用r(只讀)方式打開文件只能用于程序從文件輸入數(shù)據(jù),不能向文件輸出數(shù)據(jù),而且要求該文件已經(jīng)存在,不能打開一個并不存在的用于“r”方式的文件,否則函數(shù)fopen()將返回空指針NULL。(2)用w(只寫)方式打開的文件只能用于向文件輸出數(shù)據(jù),不能從該文件中輸入數(shù)據(jù),如果打開時原文件不存在,則新建一個以指定名字命名的文件,如果原來已存在一個以該文件名命名的文件,則在打開時將該文件刪去,然后重新建立一個以該名字命名的新文件。(3)用a(追加)方式打開的文件,表示不刪除原文件里的數(shù)據(jù),而是從文件的末尾開始填加數(shù)據(jù),要求被打開的文件已經(jīng)存在,打開后,文件的位置指針將定位在文件的末尾,如果打開的文件已經(jīng)存在,則函數(shù)fopen()返回一個空指針NULL。(4)用r+,w+,a+(讀/寫)方式打開的文件,既可以從文件輸入數(shù)據(jù),也可以向文件輸出數(shù)據(jù),其中r+只允許打開已存在的文件,用w+方式打開,則系統(tǒng)新建一個文件,先向文件輸出數(shù)據(jù),然后才能從文件中輸入數(shù)據(jù)。用a+方式是打開已經(jīng)存在的文件,并且文件的位置指針定位在文件的末尾,先準備向文件添加數(shù)據(jù),以后也可以從文件中輸入數(shù)據(jù)。(5)上述打開的文件都是針對文本文件,如果要打開二進制文件,必須在使用方式后面添上字符b,如rb表示以只讀方式打開一個二進制文件。(6)如果用r方式打開一個并不存在的文件,或磁盤損壞、磁盤空間不足等情況下打開文件,都會使打開文件失敗。此時fopen函數(shù)將返回一個空指針NULL。所以常用下面的方法打開一個文件。if((fp=fopen(“file1”,”r”))==NULL){printf(“cannotopenthisfile\n”);exit(0);

)這個程序的意義是:如果在以只讀的方式打開文件file1時,返回的是空指針NULL,則表示該文件打開失敗,則在屏幕上給出提示信息“cannotopenthisfile”。Exit函數(shù)的作用是關(guān)閉所有文件,終止正調(diào)用的過程。三、文件的關(guān)閉(fclose()函數(shù))一個文件使用完后應該及時關(guān)閉它,以防止它再被誤用,一方面可以避免文件的數(shù)據(jù)丟失,另一方面是及時釋放內(nèi)存,減少系統(tǒng)資源的占用?!瓣P(guān)閉”就是指文件指針變量不再指向該文件,也就是文件指針變量與該文件“斷開”,此后不能通過該指針變量對原來與其相聯(lián)系的文件進行讀寫操作,除非再次打開,使文件指針變量重新指向該文件。fclose函數(shù)的調(diào)用方式如下:FILE*fp;fclose(fp);其中,fp是打開此文件時所返回的指針值,fclose()的作用是撤消文件指針變量與文件的聯(lián)系,同時自動釋放分配給文件的緩沖區(qū)。fclose函數(shù)也返回一個整型值,如果正常執(zhí)行了文件關(guān)閉操作,則返回值為0;否則返回EOF,EOF是系統(tǒng)在頭stdio.h中定義的符號常量,其值為-1。【案例9-1】編寫程序?qū)盤上的文件file1.txt打開,如果文件存在,則以讀的方式打開,否則說明文件不存在。#include<stdio.h>main(){FILE*fp;/*定義一個文件指針fp*/fp=fopen(“d:\\file1.txt”,”r”);/*用“讀”方式打開文本文件file1.txt*/if(fp==NULL){printf(“該文件不存在\n”);exit(0);}elseprintf(“文件已經(jīng)打開\n”);fclose(fp);/*關(guān)閉文本文件file1.txt*/}【注意】如果D盤根目錄下存在文件file1.txt,以上程序運行后在屏幕上顯示文件已經(jīng)打開,如果文件不存在,屏幕上顯示該文件不存在,并結(jié)束程序的運行。第三節(jié)文件的順序讀寫在C語言中提供了多種文件讀寫的函數(shù):一、字符讀寫函數(shù)fgetc和fputc1、fgetc函數(shù)它的功能是以字符(字節(jié))為單位,每次可從文件讀出一個字符。函數(shù)的調(diào)用方式為:fgetc(FILE*fp);其中fp是文件指針變量,所指向的文件必須是以讀或讀寫方式打開的。返回值:fgetc函數(shù)有一個返回值,如果正常返回,則返回讀取的字符代碼。否則返回EOF;如果讀到文件結(jié)束符(^Z)時,也返回EOF,可以用它來判斷是否讀完了文件中的數(shù)據(jù)。2、fputc函數(shù)它的功能是以字符(字節(jié))為單位,每次可向文件寫入一個字符。函數(shù)的調(diào)用方式為:intfputc(charch,FILE*fp);其中ch是要輸出的字符,它可以是字符常量或字符變量。fp是文件指針變量,指向當前打開的文件。返回值:fputc函數(shù)有一個返回值,如果寫入成功則返回寫入的字符,如果失敗則返回一個EOF。EOF是在stdio.h文件中定義的符號常量,值為-1?!景咐?-2】從鍵盤輸入一個字符串,寫入文件test.txt中,將小寫字母全部轉(zhuǎn)換成大寫字母,再把該文件內(nèi)容讀出來顯示在屏幕上。#include<stdio.h>main(){FILE*fp;charch1,ch[50];inti=0;fp=fopen("test.txt","w");/*用"寫"方式打開文本文件test.txt*/printf("請輸入一個字符串:\n");while((ch[i]=getchar())!='\n')/*輸入字符直到按回車為止*/{if(ch[i]>='a'&&ch[i]<='z')/*判斷字符是否是小寫字母*/ch[i]=ch[i]-32;/*如果是小寫字母,就轉(zhuǎn)換成大寫字母*/fputc(ch[i],fp);/*將轉(zhuǎn)換后的字符寫入文件指針fp所指的文件中*/i++;}fclose(fp);if((fp=fopen("test.txt","r"))==NULL)/*用"讀"方式打開文本文件test.txt*/ { printf("不能打開文件.\n"); exit(0); }ch1=fgetc(fp);/將字符從文件指針fp所指的文件中讀出*/while(ch1!=EOF)/*判斷是否到了文件的末尾*/{putchar(ch1);ch1=fgetc(fp);}printf("\n");fclose(fp);}【說明】(1)程序中首先以寫的方式打開文件,每輸入一個字符,文件內(nèi)部位置指針向后移動一個字節(jié)。寫入完畢,該指針已經(jīng)指向文件末尾。如果要把文件從頭讀出,必須先關(guān)閉文件,再將文件以讀的方式打開。(2)第二個while循環(huán)每執(zhí)行一次,fgetc函數(shù)就從fp所指的文件中讀出一個字符給字符變量ch1,并且用putchar函數(shù)將它顯示在屏幕上。二、字符串的讀寫函數(shù)fputs和fgets1、fgets函數(shù)它的功能是從指定的文件中讀一個字符串到字符數(shù)組中。函數(shù)的調(diào)用方式為:fgets(char*str,intn,FILE*fp);其中str為讀取到的字符串的地址,可以是指針,也可以是數(shù)組,n為限定每次讀取的字符個數(shù),fp為指定讀取的文件指針。返回值:從fp所指向的文件當前讀寫位置開始,最多讀入(n-1)個字符(包括換行符),在讀入的最后一個字符后加上字符串結(jié)束標志'\0'。正常返回值為str的首地址,當讀到文件末尾或出錯時,返回NULL。例如:fgets(str,n,fp);其意義是從fp所指的文件中讀取n-1個字符送入字符數(shù)組str中。2、fputs函數(shù)它的功能是是向指定的文件寫入一個字符串。函數(shù)的調(diào)用方式為:fputs(char*str,FILE*fp);其中str為指定輸出的字符串,它可以是指針、數(shù)組名或字符串,fp為指定的輸出文件。返回值:正常返回值為所輸出的字符串中最后一個字符的ASCII值,如果向文件寫入字符串不成功,則返回值為EOF。例如:fputs("wxm",fp);其意義是把字符串"wxm"寫入fp所指的文件中?!景咐?-3】編制一個程序?qū)崿F(xiàn)文本文件的復制功能。分析:將文件1的內(nèi)容復制到文件2中,通過while循環(huán)每次使用fgets函數(shù)從文件1中讀取80個字符寫入文件2中,直到遇見文件1的結(jié)束標志EOF。include<stdio.h>main(){FILE*fp1,*fp2;charstring[81];/*最多保存80個字符,外加一個字符串結(jié)束標志*/charfile1[20],file2[20];printf("輸入文件名1:");scanf("%s",file1);printf("輸入文件名2:");scanf("%s",file2);if((fp1=fopen(file1,"r"))==NULL)/*以"只讀"方式打開文件1*/{printf("文件不能讀");exit(0);}if((fp2=fopen(file2,"w"))==NULL)/*以"寫"方式打開文件2*/{printf("文件不能寫");exit(0);}while(fgets(string,81,fp1)!=NULL)/*如果未讀到文件末尾(EOF),函數(shù)不會返回NULL,繼續(xù)循環(huán)(執(zhí)行循環(huán)體)*//*從fp1所指向的文件一次讀80個字符,遇換行或EOF,提前帶回字符串*/printf("%s",string);/*打印字符串*/fputs(string,fp2);/*將字符串寫入fp2所指向的文件*/fclose(fp1);/*關(guān)閉文件*/fclose(fp2);}【案例9-4】現(xiàn)在我們將在前面幾章編寫的“學生成績管理系統(tǒng)”中的輸入函數(shù)shuru()做一些小的修改,將學生的各項信息從鍵盤輸入后,直接存放在一個文本文件---成績統(tǒng)計.txt里,以方便我們進行成績的管理。#defineN1000#include<stdio.h>#include<stdlib.h>structscore{intmingci;charxuehao[8];charmingzi[20];floatscor[6];}data,info[1000];inti,j,k=0;chartemp[20],ch;FILE*fp;voidshuru(){chartemp[20],ch;chars[30];if((fp=fopen("成績統(tǒng)計.txt","a+"))==NULL){printf("cannotopenthisfile.\n");getch();exit(0);}for(i=0;i<=N;i++){printf("\n請輸入學號:");gets(data.xuehao);fputs(data.xuehao,fp);printf("請輸入名字:");gets(data.mingzi);fputs(data.mingzi,fp);printf("請輸入語文分數(shù):");gets(temp);data.scor[0]=atof(temp);/*將字符串轉(zhuǎn)換成浮點數(shù)*/fputs(temp,fp);printf("請輸入數(shù)學分數(shù):");gets(temp);data.scor[1]=atof(temp);fputs(temp,fp);printf("請輸入英語分數(shù):");gets(temp);data.scor[2]=atof(temp);fputs(temp,fp);

printf("請輸入物理分數(shù):");gets(temp);data.scor[3]=atof(temp);fputs(temp,fp);printf("請輸入化學分數(shù):");gets(temp);data.scor[4]=atof(temp);fputs(temp,fp);data.scor[5]=data.scor[0]+data.scor[1]+data.scor[2]+data.scor[3]+data.scor[4];sprintf(s,"%4.1f",data.scor[5]);/*將浮點數(shù)轉(zhuǎn)換成字符串*/fputs(s,fp);}fclose(fp);}main(){shuru();}三、數(shù)據(jù)塊讀寫函數(shù)fwrite和fread它的功能是以一個指定大小的數(shù)據(jù)塊(由多個數(shù)據(jù)組成)為單位從文件中讀數(shù)據(jù)。函數(shù)的調(diào)用方式如下:fread(buffer,size,count,fp);fwrite(buffer,size,count,fp);函數(shù)功能:用來讀寫一個數(shù)據(jù)塊。其中:(1)buffer:是一個指針,對fread來說,它是讀入數(shù)據(jù)的存放地址。對fwrite來說,是要輸出數(shù)據(jù)的地址。(2)size:是指出一次讀寫一個數(shù)據(jù)塊時,數(shù)據(jù)塊中所包含的字節(jié)數(shù)。(3)count:是指要讀寫的數(shù)據(jù)塊塊數(shù)。(4)fp:是文件指針。返回值:如果函數(shù)執(zhí)行成功,則返回值為count;如果函數(shù)執(zhí)行出錯,則出現(xiàn)錯誤提示;如果size或count為0,則返回值為0?!景咐?-5】從鍵盤輸入3個員工的有關(guān)數(shù)據(jù),將它們存入文件staff,然后再從文件中讀出數(shù)據(jù),顯示在屏幕上。#include"stdio.h"voidfsave();/*原型*/structstaff/*結(jié)構(gòu)體類型的聲明*/{intnum;charname[10];intage;charaddress[15];}st[3],st1[3];/*定義一個結(jié)構(gòu)體類型數(shù)組*/voidfsave(){FILE*fp;inti;if((fp=fopen("staff","wb"))==NULL)/*以"寫"的方式打開一個二進制文件,然后判斷是否打開成功*/{printf("cannotopenfile\n");exit(0);}for(i=0;i<3;i++)if(fwrite(&st[i],sizeof(structstaff),1,fp)!=1)/*把讀取的數(shù)據(jù)塊寫入文件,并判斷是否到文件末尾或出錯*/printf("filereaderror\n");/*寫過程中的出錯處理*/fclose(fp);/*關(guān)閉文件*/}voidmain(){inti;FILE*fp;for(i=0;i<3;i++)/*從鍵盤讀入員工數(shù)據(jù)*/scanf("%s%d%d%s",st[i].name,&st[i].num,&st[i].age,st[i].address);fsave();/*將員工數(shù)據(jù)存入磁盤文件*/if((fp=fopen("staff","rb"))==NULL)/*以"讀"的方式打開一個二進制文件,然后判斷是否打開成功*/{printf("cannotopenfile\n");exit(0);}for(i=0;i<3;i++)if(fread(&st1[i],sizeof(structstaff),1,fp)!=1)/*從staff文件中讀取一個數(shù)據(jù)塊,并判斷是否到文件末尾或出錯*/{if(feof(fp))return;/*如果到文件末尾則返回*/printf("filereaderror\n");}for(i=0;i<3;i++)/*j將讀出的數(shù)據(jù)在屏幕上顯示出來*/printf("%-10s%4d%4d%-15s\n",st1[i].name,st1[i].num,st1[i].age,st1[i].address);}【說明】(1)結(jié)構(gòu)體類型數(shù)組st有3個元素,每個元素都是結(jié)構(gòu)體類型,代表3個數(shù)據(jù)塊。(2)執(zhí)行fread(&st[i],sizeof(structstaff),1,fp)語句后,從文件起始位置起,將結(jié)構(gòu)體類型數(shù)組st中的3個元素的有關(guān)數(shù)據(jù)一一寫到文件中,用表達式sizeof(structstaff)計算該數(shù)據(jù)塊的字節(jié)數(shù),數(shù)字1表示每次寫1個數(shù)據(jù)塊。第四節(jié)隨機文件的讀寫前面介紹的文件讀寫方式都是順序讀寫,從文件的開頭依次順序讀寫每一個數(shù)據(jù)。由指向文件的指針自動移位。但在實際對文件的應用中,還往往需要對文件中某一個特定的數(shù)據(jù)進行處理,這就要求對文件具有隨機讀寫的功能,也就是強制將文件的指針指向用戶所希望的指定位置。這就是所謂對文件的定位與隨機讀寫,C語言對文件的定位提供了三個函數(shù)。一、位置復位函數(shù)rewind()函數(shù)的調(diào)用方式如下:

Rewind(fp);

其中fp是文件指針。此函數(shù)沒有返回值。函數(shù)功能:使fp指定的文件的位置指針重新定位到文件的開頭位置。二、改變文件位置指針函數(shù)fseek()函數(shù)的調(diào)用形式:

fseek(fp,offset,position)函數(shù)功能:將文件內(nèi)部位置指針移動到指定位置,如果函數(shù)讀寫指針移動失敗,返回值為-1。參數(shù)說明:fp是文件指針,position是起始點,表示以文件的什么位置為基準進行移動。positon的值用整常數(shù)表示,ANSIC允許它有下列三個值之一:0-----文件的開頭;1-----文件的當前位置;2-----文件的末尾。offset是位移量,它表示以起始點position到要確定的新位置的字節(jié)數(shù)。ANSIC要求位移量是long類型數(shù)據(jù),以便在文件長度大于64KB時不會出錯。如果位移量為正數(shù),是從文件開頭向文件末尾移動,如果如果位移量為負數(shù),表示是從文件末尾向文件開頭移動。fseek函數(shù)一般用于二進制文件。例如:Fseek(fp,30L,0);/*將文件位置指針移動到文件頭起始第30個字節(jié)處*/Fseek(fp,30L,1);/*將文件位置指針從當前位置向前(文件尾方向)移動30個字節(jié)*/Fseek(fp,-30L,2);/*將文件位置指針從文件末尾向后(文件頭方向)移動30個字節(jié)*/三、ftell函數(shù)函數(shù)的調(diào)用方式如下:

ftell(fp);其中fp是一個文件指針。函數(shù)功能:得到fp所指向文件的當前位置,該值是一個長整型數(shù),是文件位置指針從文件開始處到當前位置的位移量的字節(jié)數(shù)。如果函數(shù)的返回值為-1L,表示出錯。第五節(jié)項目任務:項目案例綜合實現(xiàn)【項目案例】“學生成績管理系統(tǒng)”設(shè)計實現(xiàn)分析:在以前的程序中,當我們處理數(shù)據(jù)時,總是通過鍵盤對數(shù)據(jù)一一進行輸入,這在反復處理大批量的數(shù)據(jù)的時候就很不方便。那我們能否預先將數(shù)據(jù)統(tǒng)一輸入,再來對數(shù)據(jù)進行處理呢?答案是肯定的,最常用的方法就是將這些數(shù)據(jù)寫入到一個文件里,再將這個文件存放在磁盤上,需要時再將數(shù)據(jù)從該文件中讀取并進行處理。我們現(xiàn)在就采用fwrite函數(shù)將學生的成績信息保存在磁盤文件,然后將這些數(shù)據(jù)通過fread函數(shù)從文件中讀出。全部程序代碼如下:#include"stdio.h"/*I/O函數(shù)*/#include"stdlib.h"/*其它說明*/#include"string.h"/*字符串函數(shù)*/#include"conio.h"/*屏幕操作函數(shù)*/#include"mem.h"/*內(nèi)存操作函數(shù)*/#include"ctype.h"/*字符操作函數(shù)*/#include"alloc.h"/*動態(tài)地址分配函數(shù)*/structscore{intmingci;charxuehao[8];charmingzi[20];floatscor[6];}data,info[1000];inti,j,k=0;chartemp[20],ch;FILE*fp,*fp1;voidshuru(){if((fp=fopen("成績統(tǒng)計.txt","a+"))==NULL){printf("cannotopenthisfile.\n");getch();exit(0);}for(i=0;i<=1000;i++){printf("\n請輸入學號:");gets(data.xuehao);printf("請輸入名字:");gets(data.mingzi);printf("請輸入語文分數(shù):");gets(temp);data.scor[0]=atof(temp);printf("請輸入數(shù)學分數(shù):");gets(temp);data.scor[1]=atof(temp);printf("請輸入英語分數(shù):");gets(temp);data.scor[2]=atof(temp);printf("請輸入物理分數(shù):");gets(temp);data.scor[3]=atof(temp);printf("請輸入化學分數(shù):");gets(temp);data.scor[4]=atof(temp);data.scor[5]=data.scor[0]+data.scor[1]+data.scor[2]+data.scor[3]+data.scor[4];

fwrite(&data,sizeof(data),1,fp);printf("是否繼續(xù)輸入?y/n");ch=getche();if(ch=='n'||ch=='N')break;}fclose(fp);}voidxianshi(){floats;intn;if((fp=fopen("成績統(tǒng)計.txt","r+"))==NULL){printf("Cannotreadingthisfile.\n");exit(0);}for(i=0;i<=1000;i++){if((fread(&info[i],sizeof(info[i]),1,fp))!=1)break;}printf("\n學號名字語文數(shù)學英語物理化學總分\n");for(j=0,k=1;j<i;j++,k++){info[j].mingci=k;printf("%6s%8s%3.1f%3.1f%3.1f%3.1f%3.1f%3.1f\n",info[j].xuehao,info[j].mingzi,info[j].scor[0],info[j].scor[1],info[j].scor[2],info[j].scor[3],info[j].scor[4],info[j].scor[5]);}getch();fclose(fp);}voidxiugai(){if((fp=fopen("成績統(tǒng)計.txt","r+"))==NULL||(fp1=fopen("temp.txt","w+"))==NULL){printf("Cannotopenthisfile.\n");exit(0);}printf("\n請輸入修改學號:");scanf("%d",&i);getchar();while((fread(&data,sizeof(data),1,fp))==1){j=atoi(data.xuehao);if(j==i){printf("學號:%s\n名字:%s\n",data.xuehao,data.mingzi);printf("請輸入名字:");gets(data.mingzi);printf("請輸入語文分數(shù):");gets(temp);data.scor[0]=atof(temp);printf("請輸入數(shù)學分數(shù):");gets(temp);data.scor[1]=atof(temp);printf("請輸入英語分數(shù):");gets(temp);data.scor[2]=atof(temp);printf("請輸入物理分數(shù):");gets(temp);data.scor[3]=atof(temp);printf("請輸入化學分數(shù):");gets(temp);data.scor[4]=atof(temp);data.scor[5]=data.scor[0]+data.scor[1]+data.scor[2]+data.scor[3]+data.scor[4];

}fwrite(&data,sizeof(data),1,fp1);}fseek(fp,0L,0);fseek(fp1,0L,0);while((fread(&data,sizeof(data),1,fp1))==1){fwrite(&data,sizeof(data),1,fp);}fclose(fp);fclose(fp1);}voidchazhao(){if((fp=fopen("成績統(tǒng)計.txt","r"))==NULL){printf("\nCannotopenthisfile.\n");exit(0);}printf("\n請輸入學號查看:");scanf("%d",&i);while(fread(&data,sizeof(data),1,fp)==1){j=atoi(data.xuehao);if(i==j){ printf("學號:%s名字:%s

溫馨提示

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

提交評論