![C語(yǔ)言程序設(shè)計(jì)課件:文件_第1頁(yè)](http://file4.renrendoc.com/view8/M02/25/01/wKhkGWccOp6AGdWDAAEw_I_xpxk291.jpg)
![C語(yǔ)言程序設(shè)計(jì)課件:文件_第2頁(yè)](http://file4.renrendoc.com/view8/M02/25/01/wKhkGWccOp6AGdWDAAEw_I_xpxk2912.jpg)
![C語(yǔ)言程序設(shè)計(jì)課件:文件_第3頁(yè)](http://file4.renrendoc.com/view8/M02/25/01/wKhkGWccOp6AGdWDAAEw_I_xpxk2913.jpg)
![C語(yǔ)言程序設(shè)計(jì)課件:文件_第4頁(yè)](http://file4.renrendoc.com/view8/M02/25/01/wKhkGWccOp6AGdWDAAEw_I_xpxk2914.jpg)
![C語(yǔ)言程序設(shè)計(jì)課件:文件_第5頁(yè)](http://file4.renrendoc.com/view8/M02/25/01/wKhkGWccOp6AGdWDAAEw_I_xpxk2915.jpg)
版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
文件第一節(jié)文件的基本概念與分類(lèi)第二節(jié)打開(kāi)和關(guān)閉文件第三節(jié)文件的順序讀寫(xiě)第四節(jié)隨機(jī)文件的讀寫(xiě)第五節(jié)項(xiàng)目任務(wù):項(xiàng)目案例綜合實(shí)現(xiàn)第一節(jié)文件的基本概念與分類(lèi)文件是程序設(shè)計(jì)中一個(gè)重要的概念。所謂“文件”一般指存儲(chǔ)在外部介質(zhì)(如磁盤(pán)等)上的一組相關(guān)數(shù)據(jù)的有序集合。這個(gè)數(shù)據(jù)集有一個(gè)名稱(chēng),叫做文件名。實(shí)際上在前面的各章中我們已經(jīng)多次使用了文件,例如源程序文件、目標(biāo)文件、可執(zhí)行文件、庫(kù)文件(頭文件)等。操作系統(tǒng)是以文件為單位對(duì)數(shù)據(jù)進(jìn)行管理的,也就是說(shuō),如果想找到存儲(chǔ)在外部介質(zhì)上的數(shù)據(jù),必須先按文件名找到所指定的文件,然后再?gòu)脑撐募凶x取數(shù)據(jù)。向外部介質(zhì)上存儲(chǔ)數(shù)據(jù)也必須先建立一個(gè)文件,才能向它輸出(寫(xiě))數(shù)據(jù)。從文件數(shù)據(jù)的組織形式即數(shù)據(jù)在磁盤(pán)上的存儲(chǔ)形式看,C語(yǔ)言的文件可分為ASCII文件和二進(jìn)制文件。ASCII文件:又稱(chēng)為文本文件(text)文件,特點(diǎn)是數(shù)據(jù)在外部介質(zhì)中存放時(shí)一個(gè)字節(jié)存放一個(gè)ASCII碼字符。例如:整數(shù)1024的ASCII碼存儲(chǔ)形式為:上面可以看出,以ASCII形式存放需要占用4個(gè)字節(jié)。二進(jìn)制文件:將內(nèi)存中的數(shù)據(jù)存入磁盤(pán)的時(shí)候不需要進(jìn)行數(shù)據(jù)轉(zhuǎn)換,在內(nèi)存中的數(shù)據(jù)形式與輸出到外部文件中的數(shù)據(jù)形式完全一致。int型的1024若按二進(jìn)制輸出則占用2個(gè)字節(jié)。例如:整數(shù)1024的二進(jìn)制存儲(chǔ)形式為:001100010011000000110010001101000000010000000000從上面可以看出,在ASCII文件中采用ASCII碼的形式保存數(shù)據(jù),每個(gè)字符都是以ASCII碼形式存儲(chǔ),方便了對(duì)字符的逐個(gè)處理,在操作系統(tǒng)下也可以直接識(shí)別,但占用的磁盤(pán)存儲(chǔ)空間較多,同時(shí)還要付出由二進(jìn)制形式向ASCII碼轉(zhuǎn)換的時(shí)間開(kāi)銷(xiāo)。用二進(jìn)制形式存儲(chǔ)可以節(jié)省磁盤(pán)空間和轉(zhuǎn)換時(shí)間,但輸出的形式由于是內(nèi)存中的表示形式,所以一般不能直接識(shí)別。因此,一般中間數(shù)據(jù)用二進(jìn)制文件保存,輸入輸出使用ASCII文件。從用戶(hù)使用的觀點(diǎn)看,文件可分為普通文件和設(shè)備文件。普通文件是指駐留在磁盤(pán)或其它外部介質(zhì)上的一個(gè)有序數(shù)據(jù)集,可以是源文件、目標(biāo)文件、可執(zhí)行程序;也可以是一組待輸入處理的原始數(shù)據(jù),或者是一組輸出的結(jié)果。設(shè)備文件是指與主機(jī)相聯(lián)的各種外部設(shè)備,如顯示器、打印機(jī)、鍵盤(pán)等。例如將鍵盤(pán)看作是輸入文件,將顯示器和打印機(jī)看作是輸出文件。在C語(yǔ)言中,對(duì)外部設(shè)備的輸入輸出處理過(guò)程就是讀寫(xiě)設(shè)備文件的過(guò)程。例如:將打印機(jī)作為設(shè)備文件時(shí),可使用由系統(tǒng)命名的PRN文件(即打印機(jī)文件)直接輸出,所有向PRN文件傳送信息的操作就是向打印機(jī)輸出打印信息。通常把顯示器定義為標(biāo)準(zhǔn)輸出文件,一般情況下在屏幕上顯示有關(guān)信息就是向標(biāo)準(zhǔn)輸出文件輸出。如前面經(jīng)常使用的printf,putchar函數(shù)就是這類(lèi)輸出。鍵盤(pán)通常被指定為標(biāo)準(zhǔn)的輸入文件,從鍵盤(pán)上輸入就意味著從標(biāo)準(zhǔn)輸入文件上輸入數(shù)據(jù)。scanf,getchar函數(shù)就屬于這類(lèi)輸入。因此,C語(yǔ)言中可將普通文件和設(shè)備文件統(tǒng)一作為邏輯文件來(lái)看待并采用相同的操作方法,從而大大地方便了程序設(shè)計(jì)。從C語(yǔ)言處理文件的方法看可以將文件分為“緩沖文件系統(tǒng)”和“非緩沖文件系統(tǒng)”兩類(lèi)。緩沖文件系統(tǒng)是指對(duì)每個(gè)正在使用的文件,系統(tǒng)自動(dòng)地在內(nèi)存區(qū)開(kāi)辟一個(gè)緩沖區(qū)。從內(nèi)存向磁盤(pán)輸出數(shù)據(jù)必須先送到內(nèi)存中的緩沖區(qū),裝滿(mǎn)緩沖區(qū)后才一起送到磁盤(pán)。如果從磁盤(pán)向內(nèi)存讀入數(shù)據(jù),則從磁盤(pán)文件中先將一批數(shù)據(jù)輸入到內(nèi)存緩沖區(qū),然后再?gòu)木彌_區(qū)逐個(gè)地將數(shù)據(jù)送到程序數(shù)據(jù)區(qū)。ANSIC只采用緩沖文件系統(tǒng)。非緩沖文件系統(tǒng)是指系統(tǒng)不自動(dòng)開(kāi)辟確定大小的緩沖區(qū),而是由程序?yàn)槊恳粋€(gè)文件設(shè)定確定大小的緩沖區(qū),它占用的是操作系統(tǒng)的緩沖區(qū),而不是用戶(hù)存儲(chǔ)區(qū)。第二節(jié)打開(kāi)和關(guān)閉文件程序中要實(shí)現(xiàn)對(duì)文件的處理,先必須在內(nèi)部文件與外部文件之間建立聯(lián)系,打開(kāi)文件,所謂打開(kāi)文件,實(shí)際上是建立文件的各種有關(guān)信息,并使文件指針指向該文件,然后才可對(duì)文件進(jìn)行操作。文件最基本的操作是讀寫(xiě)操作,操作完成后應(yīng)當(dāng)切斷內(nèi)部文件與外部文件之間的聯(lián)系,關(guān)閉文件,也就是要斷開(kāi)文件指針與文件之間的聯(lián)系。對(duì)文件進(jìn)行的所有操作通過(guò)C編譯系統(tǒng)提供的標(biāo)準(zhǔn)函數(shù)完成,這些函數(shù)的信息包含在頭文件“stdio.h”中。一、文件指針要調(diào)用一個(gè)文件,需要以下信息:(1)文件當(dāng)前的讀寫(xiě)位置,該位置指文件存放在哪個(gè)磁介質(zhì)中。(2)與該文件對(duì)應(yīng)的內(nèi)存緩沖區(qū)的地址,緩沖區(qū)的地址一般由系統(tǒng)自動(dòng)提供。(3)緩沖區(qū)中未被處理的字符數(shù),即是否有數(shù)據(jù)未被處理。(4)文件操作方法,指讀數(shù)據(jù)還是寫(xiě)數(shù)據(jù)。緩沖區(qū)為每一個(gè)文件開(kāi)辟一個(gè)“文件信息區(qū)”用來(lái)存放以上這些信息,這個(gè)信息區(qū)在內(nèi)存中,是一個(gè)結(jié)構(gòu)體變量。只要程序用到一個(gè)文件,系統(tǒng)就要為此文件開(kāi)辟一個(gè)這樣的一個(gè)結(jié)構(gòu)體變量。有幾個(gè)文件,就開(kāi)辟幾個(gè)這樣的一個(gè)結(jié)構(gòu)體變量,分別用來(lái)存放各個(gè)文件的有關(guān)信息。這些結(jié)構(gòu)體變量不用變量名來(lái)標(biāo)識(shí),而是設(shè)置一個(gè)指向該結(jié)構(gòu)體變量的指針變量,通過(guò)它來(lái)訪問(wèn)該結(jié)構(gòu)體變量。因此,在C語(yǔ)言中用一個(gè)指針變量指向一個(gè)文件,這個(gè)指針?lè)Q為文件指針。通過(guò)文件指針就可對(duì)它所指的文件進(jìn)行各種操作。定義說(shuō)明文件指針的一般形式為:FILE*指針變量標(biāo)識(shí)符;其中FILE應(yīng)為大寫(xiě),它實(shí)際上是由系統(tǒng)定義的一個(gè)結(jié)構(gòu),該結(jié)構(gòu)中含有文件名、文件狀態(tài)和文件當(dāng)前位置等信息。在編寫(xiě)源程序時(shí)不必關(guān)心FILE結(jié)構(gòu)的細(xì)節(jié)。例如:FILE*fp;表示fp是指向FILE結(jié)構(gòu)的指針變量,通過(guò)fp即可找存放某個(gè)文件信息的結(jié)構(gòu)變量,然后按結(jié)構(gòu)變量提供的信息找到該文件,實(shí)施對(duì)文件的操作。習(xí)慣上也籠統(tǒng)地把fp稱(chēng)為指向一個(gè)文件的指針。二、文件的打開(kāi)(fopen()函數(shù))所謂“打開(kāi)”,是指在程序和操作系統(tǒng)之間建立起聯(lián)系,程序把所要操作的文件的一些信息通知給操作系統(tǒng)。這些信息中除包括文件名外,還要指出讀寫(xiě)方式及讀寫(xiě)位置。如果是讀,則需要先確認(rèn)此文件是否已存在;如果是寫(xiě),則檢查原來(lái)是否有同名文件,如有則將該文件刪除,然后新建立一個(gè)文件,并將讀寫(xiě)位置設(shè)定于文件開(kāi)頭,準(zhǔn)備寫(xiě)入數(shù)據(jù)。fopen函數(shù)用來(lái)打開(kāi)一個(gè)文件,其調(diào)用的一般形式為:FILE*fp;fp=fopen(文件名,使用文件方式);其中,fp是文件指針名,“文件指針名”必須是被說(shuō)明為FILE類(lèi)型的指針變量,“文件名”是被打開(kāi)文件的文件名?!笆褂梦募绞健笔侵肝募念?lèi)型和操作要求。例如:FILE*fp;fp=fopen(“file1”,”r”);其意義是在當(dāng)前目錄下打開(kāi)文件file1,并且以“讀”方式打開(kāi),同時(shí)返回指向該文件的指針并賦給fp。又如:FILE*fp1;fp1=("d:\\file2',"w");其意義是打開(kāi)D驅(qū)動(dòng)器磁盤(pán)的根目錄下的文件file2,并且以“寫(xiě)”方式打開(kāi)。兩個(gè)反斜線“\\”中的第一個(gè)表示轉(zhuǎn)義字符,第二個(gè)表示根目錄。使用文件的方式共有12種,下表就是它們的符號(hào)和含義。表9-1文件使用方式表說(shuō)明:(1)用r(只讀)方式打開(kāi)文件只能用于程序從文件輸入數(shù)據(jù),不能向文件輸出數(shù)據(jù),而且要求該文件已經(jīng)存在,不能打開(kāi)一個(gè)并不存在的用于“r”方式的文件,否則函數(shù)fopen()將返回空指針NULL。(2)用w(只寫(xiě))方式打開(kāi)的文件只能用于向文件輸出數(shù)據(jù),不能從該文件中輸入數(shù)據(jù),如果打開(kāi)時(shí)原文件不存在,則新建一個(gè)以指定名字命名的文件,如果原來(lái)已存在一個(gè)以該文件名命名的文件,則在打開(kāi)時(shí)將該文件刪去,然后重新建立一個(gè)以該名字命名的新文件。(3)用a(追加)方式打開(kāi)的文件,表示不刪除原文件里的數(shù)據(jù),而是從文件的末尾開(kāi)始填加數(shù)據(jù),要求被打開(kāi)的文件已經(jīng)存在,打開(kāi)后,文件的位置指針將定位在文件的末尾,如果打開(kāi)的文件已經(jīng)存在,則函數(shù)fopen()返回一個(gè)空指針NULL。(4)用r+,w+,a+(讀/寫(xiě))方式打開(kāi)的文件,既可以從文件輸入數(shù)據(jù),也可以向文件輸出數(shù)據(jù),其中r+只允許打開(kāi)已存在的文件,用w+方式打開(kāi),則系統(tǒng)新建一個(gè)文件,先向文件輸出數(shù)據(jù),然后才能從文件中輸入數(shù)據(jù)。用a+方式是打開(kāi)已經(jīng)存在的文件,并且文件的位置指針定位在文件的末尾,先準(zhǔn)備向文件添加數(shù)據(jù),以后也可以從文件中輸入數(shù)據(jù)。(5)上述打開(kāi)的文件都是針對(duì)文本文件,如果要打開(kāi)二進(jìn)制文件,必須在使用方式后面添上字符b,如rb表示以只讀方式打開(kāi)一個(gè)二進(jìn)制文件。(6)如果用r方式打開(kāi)一個(gè)并不存在的文件,或磁盤(pán)損壞、磁盤(pán)空間不足等情況下打開(kāi)文件,都會(huì)使打開(kāi)文件失敗。此時(shí)fopen函數(shù)將返回一個(gè)空指針NULL。所以常用下面的方法打開(kāi)一個(gè)文件。if((fp=fopen(“file1”,”r”))==NULL){printf(“cannotopenthisfile\n”);exit(0);
)這個(gè)程序的意義是:如果在以只讀的方式打開(kāi)文件file1時(shí),返回的是空指針NULL,則表示該文件打開(kāi)失敗,則在屏幕上給出提示信息“cannotopenthisfile”。Exit函數(shù)的作用是關(guān)閉所有文件,終止正調(diào)用的過(guò)程。三、文件的關(guān)閉(fclose()函數(shù))一個(gè)文件使用完后應(yīng)該及時(shí)關(guān)閉它,以防止它再被誤用,一方面可以避免文件的數(shù)據(jù)丟失,另一方面是及時(shí)釋放內(nèi)存,減少系統(tǒng)資源的占用?!瓣P(guān)閉”就是指文件指針變量不再指向該文件,也就是文件指針變量與該文件“斷開(kāi)”,此后不能通過(guò)該指針變量對(duì)原來(lái)與其相聯(lián)系的文件進(jìn)行讀寫(xiě)操作,除非再次打開(kāi),使文件指針變量重新指向該文件。fclose函數(shù)的調(diào)用方式如下:FILE*fp;fclose(fp);其中,fp是打開(kāi)此文件時(shí)所返回的指針值,fclose()的作用是撤消文件指針變量與文件的聯(lián)系,同時(shí)自動(dòng)釋放分配給文件的緩沖區(qū)。fclose函數(shù)也返回一個(gè)整型值,如果正常執(zhí)行了文件關(guān)閉操作,則返回值為0;否則返回EOF,EOF是系統(tǒng)在頭stdio.h中定義的符號(hào)常量,其值為-1?!景咐?-1】編寫(xiě)程序?qū)盤(pán)上的文件file1.txt打開(kāi),如果文件存在,則以讀的方式打開(kāi),否則說(shuō)明文件不存在。#include<stdio.h>main(){FILE*fp;/*定義一個(gè)文件指針fp*/fp=fopen(“d:\\file1.txt”,”r”);/*用“讀”方式打開(kāi)文本文件file1.txt*/if(fp==NULL){printf(“該文件不存在\n”);exit(0);}elseprintf(“文件已經(jīng)打開(kāi)\n”);fclose(fp);/*關(guān)閉文本文件file1.txt*/}【注意】如果D盤(pán)根目錄下存在文件file1.txt,以上程序運(yùn)行后在屏幕上顯示文件已經(jīng)打開(kāi),如果文件不存在,屏幕上顯示該文件不存在,并結(jié)束程序的運(yùn)行。第三節(jié)文件的順序讀寫(xiě)在C語(yǔ)言中提供了多種文件讀寫(xiě)的函數(shù):一、字符讀寫(xiě)函數(shù)fgetc和fputc1、fgetc函數(shù)它的功能是以字符(字節(jié))為單位,每次可從文件讀出一個(gè)字符。函數(shù)的調(diào)用方式為:fgetc(FILE*fp);其中fp是文件指針變量,所指向的文件必須是以讀或讀寫(xiě)方式打開(kāi)的。返回值:fgetc函數(shù)有一個(gè)返回值,如果正常返回,則返回讀取的字符代碼。否則返回EOF;如果讀到文件結(jié)束符(^Z)時(shí),也返回EOF,可以用它來(lái)判斷是否讀完了文件中的數(shù)據(jù)。2、fputc函數(shù)它的功能是以字符(字節(jié))為單位,每次可向文件寫(xiě)入一個(gè)字符。函數(shù)的調(diào)用方式為:intfputc(charch,FILE*fp);其中ch是要輸出的字符,它可以是字符常量或字符變量。fp是文件指針變量,指向當(dāng)前打開(kāi)的文件。返回值:fputc函數(shù)有一個(gè)返回值,如果寫(xiě)入成功則返回寫(xiě)入的字符,如果失敗則返回一個(gè)EOF。EOF是在stdio.h文件中定義的符號(hào)常量,值為-1?!景咐?-2】從鍵盤(pán)輸入一個(gè)字符串,寫(xiě)入文件test.txt中,將小寫(xiě)字母全部轉(zhuǎn)換成大寫(xiě)字母,再把該文件內(nèi)容讀出來(lái)顯示在屏幕上。#include<stdio.h>main(){FILE*fp;charch1,ch[50];inti=0;fp=fopen("test.txt","w");/*用"寫(xiě)"方式打開(kāi)文本文件test.txt*/printf("請(qǐng)輸入一個(gè)字符串:\n");while((ch[i]=getchar())!='\n')/*輸入字符直到按回車(chē)為止*/{if(ch[i]>='a'&&ch[i]<='z')/*判斷字符是否是小寫(xiě)字母*/ch[i]=ch[i]-32;/*如果是小寫(xiě)字母,就轉(zhuǎn)換成大寫(xiě)字母*/fputc(ch[i],fp);/*將轉(zhuǎn)換后的字符寫(xiě)入文件指針fp所指的文件中*/i++;}fclose(fp);if((fp=fopen("test.txt","r"))==NULL)/*用"讀"方式打開(kāi)文本文件test.txt*/ { printf("不能打開(kāi)文件.\n"); exit(0); }ch1=fgetc(fp);/將字符從文件指針fp所指的文件中讀出*/while(ch1!=EOF)/*判斷是否到了文件的末尾*/{putchar(ch1);ch1=fgetc(fp);}printf("\n");fclose(fp);}【說(shuō)明】(1)程序中首先以寫(xiě)的方式打開(kāi)文件,每輸入一個(gè)字符,文件內(nèi)部位置指針向后移動(dòng)一個(gè)字節(jié)。寫(xiě)入完畢,該指針已經(jīng)指向文件末尾。如果要把文件從頭讀出,必須先關(guān)閉文件,再將文件以讀的方式打開(kāi)。(2)第二個(gè)while循環(huán)每執(zhí)行一次,fgetc函數(shù)就從fp所指的文件中讀出一個(gè)字符給字符變量ch1,并且用putchar函數(shù)將它顯示在屏幕上。二、字符串的讀寫(xiě)函數(shù)fputs和fgets1、fgets函數(shù)它的功能是從指定的文件中讀一個(gè)字符串到字符數(shù)組中。函數(shù)的調(diào)用方式為:fgets(char*str,intn,FILE*fp);其中str為讀取到的字符串的地址,可以是指針,也可以是數(shù)組,n為限定每次讀取的字符個(gè)數(shù),fp為指定讀取的文件指針。返回值:從fp所指向的文件當(dāng)前讀寫(xiě)位置開(kāi)始,最多讀入(n-1)個(gè)字符(包括換行符),在讀入的最后一個(gè)字符后加上字符串結(jié)束標(biāo)志'\0'。正常返回值為str的首地址,當(dāng)讀到文件末尾或出錯(cuò)時(shí),返回NULL。例如:fgets(str,n,fp);其意義是從fp所指的文件中讀取n-1個(gè)字符送入字符數(shù)組str中。2、fputs函數(shù)它的功能是是向指定的文件寫(xiě)入一個(gè)字符串。函數(shù)的調(diào)用方式為:fputs(char*str,FILE*fp);其中str為指定輸出的字符串,它可以是指針、數(shù)組名或字符串,fp為指定的輸出文件。返回值:正常返回值為所輸出的字符串中最后一個(gè)字符的ASCII值,如果向文件寫(xiě)入字符串不成功,則返回值為EOF。例如:fputs("wxm",fp);其意義是把字符串"wxm"寫(xiě)入fp所指的文件中?!景咐?-3】編制一個(gè)程序?qū)崿F(xiàn)文本文件的復(fù)制功能。分析:將文件1的內(nèi)容復(fù)制到文件2中,通過(guò)while循環(huán)每次使用fgets函數(shù)從文件1中讀取80個(gè)字符寫(xiě)入文件2中,直到遇見(jiàn)文件1的結(jié)束標(biāo)志EOF。include<stdio.h>main(){FILE*fp1,*fp2;charstring[81];/*最多保存80個(gè)字符,外加一個(gè)字符串結(jié)束標(biāo)志*/charfile1[20],file2[20];printf("輸入文件名1:");scanf("%s",file1);printf("輸入文件名2:");scanf("%s",file2);if((fp1=fopen(file1,"r"))==NULL)/*以"只讀"方式打開(kāi)文件1*/{printf("文件不能讀");exit(0);}if((fp2=fopen(file2,"w"))==NULL)/*以"寫(xiě)"方式打開(kāi)文件2*/{printf("文件不能寫(xiě)");exit(0);}while(fgets(string,81,fp1)!=NULL)/*如果未讀到文件末尾(EOF),函數(shù)不會(huì)返回NULL,繼續(xù)循環(huán)(執(zhí)行循環(huán)體)*//*從fp1所指向的文件一次讀80個(gè)字符,遇換行或EOF,提前帶回字符串*/printf("%s",string);/*打印字符串*/fputs(string,fp2);/*將字符串寫(xiě)入fp2所指向的文件*/fclose(fp1);/*關(guān)閉文件*/fclose(fp2);}【案例9-4】現(xiàn)在我們將在前面幾章編寫(xiě)的“學(xué)生成績(jī)管理系統(tǒng)”中的輸入函數(shù)shuru()做一些小的修改,將學(xué)生的各項(xiàng)信息從鍵盤(pán)輸入后,直接存放在一個(gè)文本文件---成績(jī)統(tǒng)計(jì).txt里,以方便我們進(jìn)行成績(jī)的管理。#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("成績(jī)統(tǒng)計(jì).txt","a+"))==NULL){printf("cannotopenthisfile.\n");getch();exit(0);}for(i=0;i<=N;i++){printf("\n請(qǐng)輸入學(xué)號(hào):");gets(data.xuehao);fputs(data.xuehao,fp);printf("請(qǐng)輸入名字:");gets(data.mingzi);fputs(data.mingzi,fp);printf("請(qǐng)輸入語(yǔ)文分?jǐn)?shù):");gets(temp);data.scor[0]=atof(temp);/*將字符串轉(zhuǎn)換成浮點(diǎn)數(shù)*/fputs(temp,fp);printf("請(qǐng)輸入數(shù)學(xué)分?jǐn)?shù):");gets(temp);data.scor[1]=atof(temp);fputs(temp,fp);printf("請(qǐng)輸入英語(yǔ)分?jǐn)?shù):");gets(temp);data.scor[2]=atof(temp);fputs(temp,fp);
printf("請(qǐng)輸入物理分?jǐn)?shù):");gets(temp);data.scor[3]=atof(temp);fputs(temp,fp);printf("請(qǐng)輸入化學(xué)分?jǐn)?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]);/*將浮點(diǎn)數(shù)轉(zhuǎn)換成字符串*/fputs(s,fp);}fclose(fp);}main(){shuru();}三、數(shù)據(jù)塊讀寫(xiě)函數(shù)fwrite和fread它的功能是以一個(gè)指定大小的數(shù)據(jù)塊(由多個(gè)數(shù)據(jù)組成)為單位從文件中讀數(shù)據(jù)。函數(shù)的調(diào)用方式如下:fread(buffer,size,count,fp);fwrite(buffer,size,count,fp);函數(shù)功能:用來(lái)讀寫(xiě)一個(gè)數(shù)據(jù)塊。其中:(1)buffer:是一個(gè)指針,對(duì)fread來(lái)說(shuō),它是讀入數(shù)據(jù)的存放地址。對(duì)fwrite來(lái)說(shuō),是要輸出數(shù)據(jù)的地址。(2)size:是指出一次讀寫(xiě)一個(gè)數(shù)據(jù)塊時(shí),數(shù)據(jù)塊中所包含的字節(jié)數(shù)。(3)count:是指要讀寫(xiě)的數(shù)據(jù)塊塊數(shù)。(4)fp:是文件指針。返回值:如果函數(shù)執(zhí)行成功,則返回值為count;如果函數(shù)執(zhí)行出錯(cuò),則出現(xiàn)錯(cuò)誤提示;如果size或count為0,則返回值為0?!景咐?-5】從鍵盤(pán)輸入3個(gè)員工的有關(guān)數(shù)據(jù),將它們存入文件staff,然后再?gòu)奈募凶x出數(shù)據(jù),顯示在屏幕上。#include"stdio.h"voidfsave();/*原型*/structstaff/*結(jié)構(gòu)體類(lèi)型的聲明*/{intnum;charname[10];intage;charaddress[15];}st[3],st1[3];/*定義一個(gè)結(jié)構(gòu)體類(lèi)型數(shù)組*/voidfsave(){FILE*fp;inti;if((fp=fopen("staff","wb"))==NULL)/*以"寫(xiě)"的方式打開(kāi)一個(gè)二進(jìn)制文件,然后判斷是否打開(kāi)成功*/{printf("cannotopenfile\n");exit(0);}for(i=0;i<3;i++)if(fwrite(&st[i],sizeof(structstaff),1,fp)!=1)/*把讀取的數(shù)據(jù)塊寫(xiě)入文件,并判斷是否到文件末尾或出錯(cuò)*/printf("filereaderror\n");/*寫(xiě)過(guò)程中的出錯(cuò)處理*/fclose(fp);/*關(guān)閉文件*/}voidmain(){inti;FILE*fp;for(i=0;i<3;i++)/*從鍵盤(pán)讀入員工數(shù)據(jù)*/scanf("%s%d%d%s",st[i].name,&st[i].num,&st[i].age,st[i].address);fsave();/*將員工數(shù)據(jù)存入磁盤(pán)文件*/if((fp=fopen("staff","rb"))==NULL)/*以"讀"的方式打開(kāi)一個(gè)二進(jìn)制文件,然后判斷是否打開(kāi)成功*/{printf("cannotopenfile\n");exit(0);}for(i=0;i<3;i++)if(fread(&st1[i],sizeof(structstaff),1,fp)!=1)/*從staff文件中讀取一個(gè)數(shù)據(jù)塊,并判斷是否到文件末尾或出錯(cuò)*/{if(feof(fp))return;/*如果到文件末尾則返回*/printf("filereaderror\n");}for(i=0;i<3;i++)/*j將讀出的數(shù)據(jù)在屏幕上顯示出來(lái)*/printf("%-10s%4d%4d%-15s\n",st1[i].name,st1[i].num,st1[i].age,st1[i].address);}【說(shuō)明】(1)結(jié)構(gòu)體類(lèi)型數(shù)組st有3個(gè)元素,每個(gè)元素都是結(jié)構(gòu)體類(lèi)型,代表3個(gè)數(shù)據(jù)塊。(2)執(zhí)行fread(&st[i],sizeof(structstaff),1,fp)語(yǔ)句后,從文件起始位置起,將結(jié)構(gòu)體類(lèi)型數(shù)組st中的3個(gè)元素的有關(guān)數(shù)據(jù)一一寫(xiě)到文件中,用表達(dá)式sizeof(structstaff)計(jì)算該數(shù)據(jù)塊的字節(jié)數(shù),數(shù)字1表示每次寫(xiě)1個(gè)數(shù)據(jù)塊。第四節(jié)隨機(jī)文件的讀寫(xiě)前面介紹的文件讀寫(xiě)方式都是順序讀寫(xiě),從文件的開(kāi)頭依次順序讀寫(xiě)每一個(gè)數(shù)據(jù)。由指向文件的指針自動(dòng)移位。但在實(shí)際對(duì)文件的應(yīng)用中,還往往需要對(duì)文件中某一個(gè)特定的數(shù)據(jù)進(jìn)行處理,這就要求對(duì)文件具有隨機(jī)讀寫(xiě)的功能,也就是強(qiáng)制將文件的指針指向用戶(hù)所希望的指定位置。這就是所謂對(duì)文件的定位與隨機(jī)讀寫(xiě),C語(yǔ)言對(duì)文件的定位提供了三個(gè)函數(shù)。一、位置復(fù)位函數(shù)rewind()函數(shù)的調(diào)用方式如下:
Rewind(fp);
其中fp是文件指針。此函數(shù)沒(méi)有返回值。函數(shù)功能:使fp指定的文件的位置指針重新定位到文件的開(kāi)頭位置。二、改變文件位置指針函數(shù)fseek()函數(shù)的調(diào)用形式:
fseek(fp,offset,position)函數(shù)功能:將文件內(nèi)部位置指針移動(dòng)到指定位置,如果函數(shù)讀寫(xiě)指針移動(dòng)失敗,返回值為-1。參數(shù)說(shuō)明:fp是文件指針,position是起始點(diǎn),表示以文件的什么位置為基準(zhǔn)進(jìn)行移動(dòng)。positon的值用整常數(shù)表示,ANSIC允許它有下列三個(gè)值之一:0-----文件的開(kāi)頭;1-----文件的當(dāng)前位置;2-----文件的末尾。offset是位移量,它表示以起始點(diǎn)position到要確定的新位置的字節(jié)數(shù)。ANSIC要求位移量是long類(lèi)型數(shù)據(jù),以便在文件長(zhǎng)度大于64KB時(shí)不會(huì)出錯(cuò)。如果位移量為正數(shù),是從文件開(kāi)頭向文件末尾移動(dòng),如果如果位移量為負(fù)數(shù),表示是從文件末尾向文件開(kāi)頭移動(dòng)。fseek函數(shù)一般用于二進(jìn)制文件。例如:Fseek(fp,30L,0);/*將文件位置指針移動(dòng)到文件頭起始第30個(gè)字節(jié)處*/Fseek(fp,30L,1);/*將文件位置指針從當(dāng)前位置向前(文件尾方向)移動(dòng)30個(gè)字節(jié)*/Fseek(fp,-30L,2);/*將文件位置指針從文件末尾向后(文件頭方向)移動(dòng)30個(gè)字節(jié)*/三、ftell函數(shù)函數(shù)的調(diào)用方式如下:
ftell(fp);其中fp是一個(gè)文件指針。函數(shù)功能:得到fp所指向文件的當(dāng)前位置,該值是一個(gè)長(zhǎng)整型數(shù),是文件位置指針從文件開(kāi)始處到當(dāng)前位置的位移量的字節(jié)數(shù)。如果函數(shù)的返回值為-1L,表示出錯(cuò)。第五節(jié)項(xiàng)目任務(wù):項(xiàng)目案例綜合實(shí)現(xiàn)【項(xiàng)目案例】“學(xué)生成績(jī)管理系統(tǒng)”設(shè)計(jì)實(shí)現(xiàn)分析:在以前的程序中,當(dāng)我們處理數(shù)據(jù)時(shí),總是通過(guò)鍵盤(pán)對(duì)數(shù)據(jù)一一進(jìn)行輸入,這在反復(fù)處理大批量的數(shù)據(jù)的時(shí)候就很不方便。那我們能否預(yù)先將數(shù)據(jù)統(tǒng)一輸入,再來(lái)對(duì)數(shù)據(jù)進(jìn)行處理呢?答案是肯定的,最常用的方法就是將這些數(shù)據(jù)寫(xiě)入到一個(gè)文件里,再將這個(gè)文件存放在磁盤(pán)上,需要時(shí)再將數(shù)據(jù)從該文件中讀取并進(jìn)行處理。我們現(xiàn)在就采用fwrite函數(shù)將學(xué)生的成績(jī)信息保存在磁盤(pán)文件,然后將這些數(shù)據(jù)通過(guò)fread函數(shù)從文件中讀出。全部程序代碼如下:#include"stdio.h"/*I/O函數(shù)*/#include"stdlib.h"/*其它說(shuō)明*/#include"string.h"/*字符串函數(shù)*/#include"conio.h"/*屏幕操作函數(shù)*/#include"mem.h"/*內(nèi)存操作函數(shù)*/#include"ctype.h"/*字符操作函數(shù)*/#include"alloc.h"/*動(dòng)態(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("成績(jī)統(tǒng)計(jì).txt","a+"))==NULL){printf("cannotopenthisfile.\n");getch();exit(0);}for(i=0;i<=1000;i++){printf("\n請(qǐng)輸入學(xué)號(hào):");gets(data.xuehao);printf("請(qǐng)輸入名字:");gets(data.mingzi);printf("請(qǐng)輸入語(yǔ)文分?jǐn)?shù):");gets(temp);data.scor[0]=atof(temp);printf("請(qǐng)輸入數(shù)學(xué)分?jǐn)?shù):");gets(temp);data.scor[1]=atof(temp);printf("請(qǐng)輸入英語(yǔ)分?jǐn)?shù):");gets(temp);data.scor[2]=atof(temp);printf("請(qǐng)輸入物理分?jǐn)?shù):");gets(temp);data.scor[3]=atof(temp);printf("請(qǐng)輸入化學(xué)分?jǐn)?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("成績(jī)統(tǒng)計(jì).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學(xué)號(hào)名字語(yǔ)文數(shù)學(xué)英語(yǔ)物理化學(xué)總分\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("成績(jī)統(tǒng)計(jì).txt","r+"))==NULL||(fp1=fopen("temp.txt","w+"))==NULL){printf("Cannotopenthisfile.\n");exit(0);}printf("\n請(qǐng)輸入修改學(xué)號(hào):");scanf("%d",&i);getchar();while((fread(&data,sizeof(data),1,fp))==1){j=atoi(data.xuehao);if(j==i){printf("學(xué)號(hào):%s\n名字:%s\n",data.xuehao,data.mingzi);printf("請(qǐng)輸入名字:");gets(data.mingzi);printf("請(qǐng)輸入語(yǔ)文分?jǐn)?shù):");gets(temp);data.scor[0]=atof(temp);printf("請(qǐng)輸入數(shù)學(xué)分?jǐn)?shù):");gets(temp);data.scor[1]=atof(temp);printf("請(qǐng)輸入英語(yǔ)分?jǐn)?shù):");gets(temp);data.scor[2]=atof(temp);printf("請(qǐng)輸入物理分?jǐn)?shù):");gets(temp);data.scor[3]=atof(temp);printf("請(qǐng)輸入化學(xué)分?jǐn)?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("成績(jī)統(tǒng)計(jì).txt","r"))==NULL){printf("\nCannotopenthisfile.\n");exit(0);}printf("\n請(qǐng)輸入學(xué)號(hào)查看:");scanf("%d",&i);while(fread(&data,sizeof(data),1,fp)==1){j=atoi(data.xuehao);if(i==j){ printf("學(xué)號(hào):%s名字:%s
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030全球滑靴式分揀系統(tǒng)行業(yè)調(diào)研及趨勢(shì)分析報(bào)告
- 2025-2030全球民用航空機(jī)翼行業(yè)調(diào)研及趨勢(shì)分析報(bào)告
- 為他人貸款合同擔(dān)保
- 叉車(chē)購(gòu)銷(xiāo)合同模板
- 2025物料購(gòu)置合同管理操作規(guī)程
- 學(xué)校商鋪?zhàn)赓U合同范本
- 提高組織和協(xié)調(diào)能力的培訓(xùn)
- 施工設(shè)計(jì)合同
- 商鋪?zhàn)赓U合同范本簡(jiǎn)單
- 人才招聘中介服務(wù)合同模板
- 安全文明施工的管理要點(diǎn)
- 附屬醫(yī)院神經(jīng)內(nèi)科中長(zhǎng)期發(fā)展規(guī)劃五年發(fā)展規(guī)劃
- 中醫(yī)中風(fēng)病(腦梗死)診療方案
- GMP-基礎(chǔ)知識(shí)培訓(xùn)
- 人教版小學(xué)六年級(jí)數(shù)學(xué)下冊(cè)(全冊(cè))教案
- 人教版二年級(jí)語(yǔ)文上冊(cè)同音字歸類(lèi)
- 高二數(shù)學(xué)下學(xué)期教學(xué)計(jì)劃
- 文學(xué)類(lèi)作品閱讀練習(xí)-2023年中考語(yǔ)文考前專(zhuān)項(xiàng)練習(xí)(浙江紹興)(含解析)
- 第五章硅酸鹽分析
- 外科學(xué)總論-第十四章腫瘤
- 網(wǎng)絡(luò)反詐知識(shí)競(jìng)賽參考題庫(kù)100題(含答案)
評(píng)論
0/150
提交評(píng)論