




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
文件輸入/輸出
——C程序與文件交互數(shù)據(jù)的方式11.1文件的基本概念11.2文件的打開(kāi)與關(guān)閉11.3順序讀/寫(xiě)數(shù)據(jù)文件11.4隨機(jī)讀/寫(xiě)數(shù)據(jù)文件11.5文件讀/寫(xiě)的出錯(cuò)檢測(cè)實(shí)操訓(xùn)練課外練習(xí)
11.1文件的基本概念
程序文件與數(shù)據(jù)文件有何異同?程序文件通過(guò)什么方式與數(shù)據(jù)文件交互?文件是指存儲(chǔ)在外部介質(zhì)上數(shù)據(jù)的集合。文件有不同的類(lèi)型。在程序設(shè)計(jì)中,主要用到程序文件和數(shù)據(jù)文件。程序文件包括源程序文件(后綴為.c)、目標(biāo)文件(后綴為.obj)、可執(zhí)行文件(后綴為.exe)等。這種文件的內(nèi)容都是程序代碼。
數(shù)據(jù)文件的內(nèi)容是供程序運(yùn)行時(shí)讀/寫(xiě)的數(shù)據(jù)。
每個(gè)文件都有一個(gè)唯一的文件標(biāo)識(shí)符,便于識(shí)別和使用。文件標(biāo)識(shí)包括3個(gè)部分,即文件路徑、主文件名和擴(kuò)展名(也稱(chēng)為后綴)。例如:D:\User\progame\file1.dat文件路徑主文件名文件擴(kuò)展名
文件路徑表示文件的存儲(chǔ)位置。文件名包括主文件名和文件擴(kuò)展名。主文件名是文件的主要標(biāo)識(shí)符號(hào),由用戶命名,擴(kuò)展名(后綴)用來(lái)表示文件的性質(zhì),一般不超過(guò)3個(gè)字符,一般采用一些約定的符號(hào)。例如dat(數(shù)據(jù)文件)、txt(文本文件)、c(C語(yǔ)言源程序)、cpp(C++語(yǔ)言源程序)、exe(可執(zhí)行文件)等。
11.1.1數(shù)據(jù)文件的概念
前面各章中,程序中數(shù)據(jù)的輸入和輸出都以終端為對(duì)象。鍵盤(pán)是常用的輸入終端,顯示器是常用的輸出終端。程序中的數(shù)據(jù)不僅可以來(lái)自終端,也可以先建立數(shù)據(jù)文件,從文件中讀??;處理的結(jié)果數(shù)據(jù)不僅可以在終端上顯示,也可以文件形式存放到磁盤(pán)文件中,供以后使用。如果文件中存放的都是數(shù)據(jù),就稱(chēng)為“數(shù)據(jù)文件”。
數(shù)據(jù)在文件中的存儲(chǔ)形式是:字符以ASCII碼形式存儲(chǔ),即一個(gè)字符占一個(gè)字節(jié);數(shù)值型數(shù)據(jù)可以按數(shù)字的ASCII碼形式存儲(chǔ),即一位數(shù)字的ASCII碼占一個(gè)字節(jié),也可以按二進(jìn)制數(shù)存儲(chǔ)。如果一個(gè)文件都以字符的ASCII碼形式存儲(chǔ)數(shù)據(jù),則稱(chēng)之為文本文件;如果一個(gè)文件都以二進(jìn)制形式存儲(chǔ)數(shù)據(jù),則稱(chēng)之為二進(jìn)制文件。文本文件(ASCII碼)中,一個(gè)數(shù)據(jù)的每一位數(shù)字的ASCII碼占一個(gè)字節(jié),調(diào)入內(nèi)存時(shí)需轉(zhuǎn)換成二進(jìn)制數(shù),存入文件時(shí)又要轉(zhuǎn)換成ASCII碼,占用內(nèi)存空間大,而且有轉(zhuǎn)換時(shí)間,但可直接向外設(shè)輸出。二進(jìn)制文件中數(shù)據(jù)的存儲(chǔ)形式與內(nèi)存存儲(chǔ)數(shù)據(jù)的形式一致,占用空間小,從文件輸入或向文件輸出時(shí)不需要轉(zhuǎn)換,但向外設(shè)輸出時(shí)需要轉(zhuǎn)換成ASCII碼。
11.1.2文件緩沖區(qū)
所謂文件緩沖區(qū),是系統(tǒng)與磁盤(pán)文件傳輸數(shù)據(jù)時(shí)在內(nèi)存中開(kāi)辟的一個(gè)暫存區(qū)域。向磁盤(pán)文件輸出數(shù)據(jù)時(shí),必須先送到緩沖區(qū),裝滿緩沖區(qū)后,才送到磁盤(pán)文件中。從磁盤(pán)讀入數(shù)據(jù)時(shí),則從磁盤(pán)文件輸入數(shù)據(jù)裝滿緩沖區(qū),然后從緩沖區(qū)將數(shù)據(jù)逐個(gè)地送到程序數(shù)據(jù)區(qū)(給程序變量),如圖11.1所示。緩沖區(qū)的大小由各個(gè)具體的C編譯系統(tǒng)確定。圖11.1系統(tǒng)與磁盤(pán)文件傳輸數(shù)據(jù)示意圖
11.1.3文件類(lèi)型指針
程序中對(duì)文件的各種操作是通過(guò)文件指針進(jìn)行的。每個(gè)文件被使用時(shí),系統(tǒng)在內(nèi)存中開(kāi)辟一個(gè)“文件信息描述區(qū)”,用來(lái)存放文件的有關(guān)信息(如文件名、文件狀態(tài)、文件使用方式、文件當(dāng)前位置、文件緩沖區(qū)所剩余的字節(jié)數(shù)等)。該信息描述區(qū)是用一個(gè)結(jié)構(gòu)體變量來(lái)實(shí)現(xiàn)的,其類(lèi)型由系統(tǒng)定義,取名為FILE。例如,一種C編譯系統(tǒng)的stdio.h中有以下的文件類(lèi)型結(jié)構(gòu)體定義:
不同的C編譯系統(tǒng)的FILE類(lèi)型包含的內(nèi)容不盡相同,但都大同小異。用戶可以在程序中使用該類(lèi)型來(lái)定義文件指針變量,通過(guò)指針變量來(lái)引用文件信息。例如:
FILE*fp1;
定義fp1為一個(gè)指向FILE類(lèi)型的指針變量。fp1指向某一個(gè)文件的文件信息區(qū)(一個(gè)結(jié)構(gòu)體變量),通過(guò)該文件信息區(qū)中的信息能夠訪問(wèn)該文件。如果程序中使用n個(gè)文件,一般應(yīng)定義n個(gè)指針變量。
11.2文件的打開(kāi)與關(guān)閉
怎樣為讀/寫(xiě)打開(kāi)或關(guān)閉一個(gè)數(shù)據(jù)文件?對(duì)文件操作之前必須打開(kāi)文件,操作結(jié)束后又要關(guān)閉文件。打開(kāi)文件的目的是建立磁盤(pán)文件與文件指針的關(guān)系,為磁盤(pán)文件在內(nèi)存中建立緩沖區(qū)。關(guān)閉文件的目的是防止文件中數(shù)據(jù)丟失,釋放文件緩沖區(qū)。C語(yǔ)言提供了文件的打開(kāi)與關(guān)閉的標(biāo)準(zhǔn)函數(shù)。
11.2.1打開(kāi)文件
使用標(biāo)準(zhǔn)函數(shù)fopen來(lái)打開(kāi)一個(gè)文件,函數(shù)調(diào)用的一般形式為
fopen("文件名","文件使用方式");
函數(shù)的功能:把指定的文件按使用方式打開(kāi),系統(tǒng)自動(dòng)給該文件建立信息描述區(qū),把文件信息區(qū)的起始地址作為返回值。通常是將返回地址賦給一個(gè)指向文件的指針變量。如果打開(kāi)文件不成功,則返回值為0。
使用文件的方式有多種,見(jiàn)表11.1。
例如:
FILE*fp;
fp=fopen("file.txt","r");
為讀文件而打開(kāi)文本文件file.txt,文件打開(kāi)成功則將該文件的指針賦給fp。
11.2.2文件的關(guān)閉
使用標(biāo)準(zhǔn)函數(shù)fclose來(lái)關(guān)閉一個(gè)已經(jīng)打開(kāi)的文件,函數(shù)調(diào)用的一般形式為
fclose(文件指針);
函數(shù)的功能:解除文件指針與文件的聯(lián)系,釋放緩沖區(qū)。如果文件關(guān)閉成功則返回值為0,否則返回EOF(-1)。
11.3順序讀/寫(xiě)數(shù)據(jù)文件
怎樣讀/寫(xiě)一個(gè)數(shù)據(jù)文件?打開(kāi)文件后,就可以進(jìn)行讀/寫(xiě)操作了。順序讀/寫(xiě)數(shù)據(jù)文件就是按文件中數(shù)據(jù)的順序進(jìn)行讀/寫(xiě)。讀數(shù)據(jù)時(shí),從文件頭開(kāi)始一個(gè)接一個(gè)讀??;寫(xiě)數(shù)據(jù)時(shí),把數(shù)據(jù)追加在當(dāng)前數(shù)據(jù)的后面。C語(yǔ)言提供了不同的讀/寫(xiě)數(shù)據(jù)文件的方式。
11.3.1字符方式讀/寫(xiě)文件
字符方式讀/寫(xiě)文件是一次從文件中讀/寫(xiě)一個(gè)字符。可通過(guò)文件的字符輸入/輸出函數(shù)調(diào)用來(lái)實(shí)現(xiàn)字符讀/寫(xiě)操作。
1.讀入字符函數(shù)fgetc
該函數(shù)調(diào)用的一般形式為
fgetc(fp);
fp是指向要輸入數(shù)據(jù)文件的指針變量。其功能是從fp所指向的文件中讀取一個(gè)字符,返回字符值;如果讀取失敗,則返回文件結(jié)束標(biāo)志EOF(-1)。
2.寫(xiě)入字符函數(shù)fputc
該函數(shù)調(diào)用的一般形式為
fputc(ch,fp);
其中,ch是要寫(xiě)入文件的字符,可以是字符常量、字符變量或字符表達(dá)式等;fp是要寫(xiě)入文件的指針變量。其功能是將字符寫(xiě)入fp所指向的文件,寫(xiě)入成功則返回值是輸出的字符,寫(xiě)入失敗則返回EOF(-1)。
例11.1從鍵盤(pán)輸入一行字符,寫(xiě)入file1.dat文件中。
編程思路:用fgetc函數(shù)從鍵盤(pán)逐個(gè)輸入字符,再用fputc函數(shù)寫(xiě)到磁盤(pán)文件中。
分析:運(yùn)行程序后,在當(dāng)前目錄下可查找到“file1.dat”,打開(kāi)文件可看到內(nèi)容是輸入的字符串。if語(yǔ)句中使用“fopen("file1.dat","w")”函數(shù)調(diào)用,先建立一個(gè)新文件,將指針賦給文件指針變量fp。在循環(huán)中將輸入的一個(gè)字符寫(xiě)入fp所指向的文件中。
例11.2將一個(gè)磁盤(pán)文件中的內(nèi)容復(fù)制到另一個(gè)磁盤(pán)文件中。現(xiàn)將例11.1建立的文件file1.dat復(fù)制到文件file2.dat中。
編程思路:從file1.dat中逐個(gè)字符讀出,再寫(xiě)入到file2.dat中。
分析:f_in=fopen("file1.dat","r")是打開(kāi)已存在的文件,使f_in指向file1.dat。fopen("file2.dat","w")是打開(kāi)不存在的文件,則建立新文件,將返回建立的文件地址賦給f_out。在while循環(huán)中的表達(dá)式測(cè)試文件是否到達(dá)結(jié)尾,未到結(jié)尾,從file1.dat讀取f_in指向的字符,寫(xiě)入file2.dat中f_out指向的位置,同時(shí)輸出當(dāng)前讀/寫(xiě)的字符。運(yùn)行程序后,在當(dāng)前目錄下可查找到“file1.dat”和“file2.dat”,打開(kāi)文件可看到兩個(gè)文件內(nèi)容相同。
11.3.2字符串方式讀/寫(xiě)文件
字符串方式讀/寫(xiě)文件是一次從文件中讀/寫(xiě)一個(gè)字符序列??赏ㄟ^(guò)文件的字符串輸入/輸出函數(shù)調(diào)用來(lái)實(shí)現(xiàn)字符串的讀/寫(xiě)操作。
1.讀取字符串函數(shù)fgets
該函數(shù)調(diào)用的一般形式為
fgets(str,n,fp);
其中,str是數(shù)組名(數(shù)組指針);n是字符串長(zhǎng)度(包含結(jié)束符);fp是要讀文件的指針變量。
函數(shù)功能:從fp所指向文件中讀取n-1個(gè)字符串,并在最后加一個(gè)字符串結(jié)束符“\0”,存入字符數(shù)組str中。讀取成功,返回?cái)?shù)組指針str,失敗則返回NULL。
2.寫(xiě)入字符串函數(shù)fputs
該函數(shù)調(diào)用的一般形式為
fputs(str,fp);
其中,str是數(shù)組名(數(shù)組指針);fp是要寫(xiě)入文件的指針變量。
函數(shù)功能:將str中的字符串寫(xiě)入fp所指向的文件中。寫(xiě)入成功返回0,寫(xiě)入失敗則返回非0。
例11.3從鍵盤(pán)輸入多個(gè)字符串,對(duì)它們按字母大小的順序排序,然后把排好序的字符串存到文件中。
編程思路:
(1)從鍵盤(pán)輸入多個(gè)字符串并存入一個(gè)二維數(shù)組中;
(2)對(duì)字符數(shù)組中的n個(gè)字符串按字母順序排序,仍存在原字符數(shù)組中;
(3)將字符數(shù)組中的字符串輸出到文件中。
分析:
(1)用單重循環(huán)實(shí)現(xiàn)3個(gè)字符串的輸入,分別存入二維數(shù)組中的3個(gè)行一維數(shù)組中。
(2)利用雙重循環(huán)實(shí)現(xiàn)3個(gè)字符串的比較和交換,將排好序的串,按序存入3個(gè)行一維數(shù)組中。
(3)用fputs函數(shù)調(diào)用,將排好序的3個(gè)行一維數(shù)組中的字符串寫(xiě)入文件。向文件中寫(xiě)入數(shù)據(jù)時(shí),只寫(xiě)入字符串的有效字符,不包括字符串結(jié)束標(biāo)志,所以“fputs(str[i],fp);”存串之后用“fputs("\n",fp);”將串結(jié)束標(biāo)志加存在串后。
11.3.3用格式化方式讀/寫(xiě)文件
C語(yǔ)言系統(tǒng)提供了與終端格式化輸入/輸出函數(shù)scanf、printf相仿的文件格式化輸入/輸出函數(shù)fscanf、fprintf。這兩個(gè)函數(shù)調(diào)用的一般形式為
fprintf(文件指針,格式字符,輸出列表);
fscanf(文件指針,格式字符,輸入列表);
其中,“格式字符”“輸入列表”“輸出列表”都同scanf、printf函數(shù)。例如:
fprintf(fp,"%d,%6.2f",i,f);
語(yǔ)句把整型i和實(shí)型變量f的值按%d、%6.2f的格式輸出到fp指向的文件中。
fscanf(fp,"%d,%f",&i,&f);
語(yǔ)句從fp所指文件中讀取一個(gè)整型數(shù)據(jù)賦給變量i,讀取一個(gè)實(shí)型數(shù)據(jù)賦給變量f。
用格式化讀/寫(xiě)函數(shù)fscanf、fprintf對(duì)磁盤(pán)文件進(jìn)行讀/寫(xiě),比較直觀,容易理解,但因輸入時(shí)要將ASCII碼轉(zhuǎn)換成二進(jìn)制形式,再保存在變量中,輸出時(shí)又要將二進(jìn)制形式轉(zhuǎn)換成ASCII碼,所以花費(fèi)的時(shí)間較多。因此,在內(nèi)存與磁盤(pán)交換數(shù)據(jù)頻繁的情況下,最好不用fscanf、fprintf函數(shù),而用下面介紹的fread、fwrite函數(shù)進(jìn)行二進(jìn)制的讀/寫(xiě)。
11.3.4用二進(jìn)制方式向文件讀/寫(xiě)一組數(shù)據(jù)
C語(yǔ)言提供的fread和fwrite函數(shù)能實(shí)現(xiàn)一次輸入/輸出一個(gè)數(shù)據(jù)塊,以二進(jìn)制形式進(jìn)行讀/寫(xiě)。
這兩個(gè)函數(shù)調(diào)用的一般形式為
fread(buffer,size,n,fp);
fwrite(buffer,size,n,fp);
參數(shù)說(shuō)明:
“buffer”表示緩沖區(qū)地址。對(duì)fread,表示從文件中讀出數(shù)據(jù)存放在內(nèi)存緩沖區(qū)首地址;對(duì)fwrite,表示向文件輸出數(shù)據(jù)的內(nèi)存緩沖區(qū)首地址。
“size”表示要讀/寫(xiě)的數(shù)據(jù)的存儲(chǔ)長(zhǎng)度(字節(jié)數(shù))。
“n”表示要讀/寫(xiě)數(shù)據(jù)的個(gè)數(shù)。
“fp”表示要讀/寫(xiě)的文件指針。
fread的功能是從fp所指向的文件中讀取n個(gè)數(shù)據(jù)(每個(gè)數(shù)據(jù)有size個(gè)字節(jié)),存到buffer為首地址的存儲(chǔ)區(qū)中。如果讀數(shù)據(jù)成功,返回輸入數(shù)據(jù)的個(gè)數(shù)n。如遇文件結(jié)束或出錯(cuò)則返回值0。
fwrite的功能是把buffer為首地址的n個(gè)數(shù)據(jù)(每個(gè)數(shù)據(jù)有size個(gè)字節(jié))寫(xiě)到fp所指向的文件中。如果寫(xiě)數(shù)據(jù)成功,返回輸出數(shù)據(jù)的個(gè)數(shù)n。
例11.4從鍵盤(pán)輸入3個(gè)學(xué)生的相關(guān)數(shù)據(jù),存到一個(gè)文件中,再?gòu)奈募凶x取數(shù)據(jù),輸出到屏幕上。
編程思路:定義有3個(gè)元素的結(jié)構(gòu)體數(shù)組,用來(lái)存放3個(gè)學(xué)生的數(shù)據(jù)。在主函數(shù)中輸入3個(gè)學(xué)生的數(shù)據(jù)。用save函數(shù)實(shí)現(xiàn)向磁盤(pán)文件輸出學(xué)生數(shù)據(jù)。在主函數(shù)中從磁盤(pán)文件讀取學(xué)生數(shù)據(jù)輸出到屏幕上。
分析:
(1)在main()函數(shù)中輸入3個(gè)學(xué)生數(shù)據(jù),存入結(jié)構(gòu)體數(shù)組stud1中。調(diào)用save函數(shù)將stud1中的數(shù)據(jù)輸出到“stu.dat”文件中。fwrite將一個(gè)結(jié)構(gòu)體數(shù)據(jù)送到“stu.dat”文件中。結(jié)構(gòu)體長(zhǎng)度用“sizeof(structstudent)”測(cè)試得到,得到的測(cè)試值為36(數(shù)據(jù)長(zhǎng)度=4+10+4+15=33,但按字節(jié)的整數(shù)倍存儲(chǔ))。
(2)在save函數(shù)中的“fopen("stu.dat","wb")”是按二進(jìn)制寫(xiě)方式打開(kāi)文件,此時(shí)文件不存在,建立一個(gè)新文件。在main函數(shù)中的“fopen("stu.dat","rb")”是為了讀而打開(kāi)二進(jìn)制文件。fread函數(shù)從“stu.dat”文件中讀取一個(gè)結(jié)構(gòu)體數(shù)據(jù)(一個(gè)學(xué)生數(shù)據(jù))存入結(jié)構(gòu)體數(shù)組stud2中,采用數(shù)組元素和結(jié)構(gòu)體成員的輸出方式輸出到屏幕上。
(3)只要修改宏定義中常數(shù)3,可實(shí)現(xiàn)任意多學(xué)生數(shù)據(jù)的輸入、存儲(chǔ)和輸出。
11.4隨機(jī)讀/寫(xiě)數(shù)據(jù)文件
怎樣按用戶需要讀/寫(xiě)數(shù)據(jù)文件中任一數(shù)據(jù)?順序讀/寫(xiě)數(shù)據(jù)文件是按數(shù)據(jù)在文件中的存儲(chǔ)順序進(jìn)行讀/寫(xiě)。隨機(jī)讀/寫(xiě)數(shù)據(jù)文件,是讀/寫(xiě)文件中任一位置的數(shù)據(jù)。
為了實(shí)現(xiàn)數(shù)據(jù)文件的讀/寫(xiě)控制,系統(tǒng)給文件內(nèi)部設(shè)置了一個(gè)位置指針。位置指針總是指向當(dāng)前要讀/寫(xiě)數(shù)據(jù)的位置。順序讀/寫(xiě)方式中,位置指針是由系統(tǒng)控制的。讀/寫(xiě)總是從文件開(kāi)頭進(jìn)行,每讀/寫(xiě)一個(gè)數(shù)據(jù),指針就后移一個(gè)數(shù)據(jù)位置,指向下一個(gè)數(shù)據(jù)位置,一直到文件尾部,指針又重返文件開(kāi)頭。隨機(jī)讀/寫(xiě)就是把位置指針控制在需要的位置上進(jìn)行讀/寫(xiě)的方式。隨機(jī)讀/寫(xiě)文件的關(guān)鍵是控制文件位置指針,也就是指針定位。C語(yǔ)言提供了文件位置指針定位的函數(shù),利用這些函數(shù),就可方便地實(shí)現(xiàn)隨機(jī)讀/寫(xiě)文件。
11.4.1位置指針定位函數(shù)
C語(yǔ)言提供了文件定位、測(cè)試和移動(dòng)函數(shù)。
1.設(shè)置文件位置指針到文件開(kāi)頭函數(shù)rewind
該函數(shù)調(diào)用的一般形式為
rewind(fp);
其中,參數(shù)fp是文件類(lèi)型指針。
函數(shù)功能:將fp所指向文件中的位置指針置于文件的開(kāi)頭位置,并清除文件結(jié)束標(biāo)志和出錯(cuò)標(biāo)志。函數(shù)無(wú)返回值。
2.檢測(cè)文件是否結(jié)束函數(shù)feof
該函數(shù)調(diào)用的一般形式為
feof(fp);
函數(shù)功能:檢測(cè)是否到fp所指向文件的結(jié)束位置,檢測(cè)到文件結(jié)束,返回非0值,否則返回0。
3.檢測(cè)文件位置指針的當(dāng)前位置ftell
該函數(shù)調(diào)用的一般形式為
ftell(fp);
函數(shù)功能:檢測(cè)fp所指向文件的當(dāng)前讀/寫(xiě)位置,返回一長(zhǎng)整型數(shù),表示當(dāng)前讀/寫(xiě)位置距文件開(kāi)頭的偏移量。偏移量是指當(dāng)前讀/寫(xiě)位置距離文件開(kāi)頭的字節(jié)數(shù)。
4.設(shè)置文件位置指針函數(shù)fseek
該函數(shù)調(diào)用的一般形式為
fseek(fp,offset,base);
其中,offset表示偏移量;base表示改變位置指針的相對(duì)基準(zhǔn)位置,參數(shù)的取值見(jiàn)表11.2。
函數(shù)功能:fp所指向文件的位置指針移到以“base”所給出的位置為基準(zhǔn)、以“offset”為偏移量的位置。移動(dòng)成功返回當(dāng)前位置,否則返回-1。
注意:文件位置指針的取值是距離文件開(kāi)頭的字節(jié)數(shù),即偏移量。知道了偏移量也就確定了讀/寫(xiě)位置。這與文件指針是截然不同的兩個(gè)概念,不能混淆。
11.4.2隨機(jī)讀/寫(xiě)文件
利用文件位置指針定位函數(shù)就可以根據(jù)需要定位讀/寫(xiě)位置,實(shí)現(xiàn)隨機(jī)讀/寫(xiě)文件中的數(shù)據(jù)。下面通過(guò)例子來(lái)說(shuō)明文件位置指針定位函數(shù)的使用及程序設(shè)計(jì)。
例11.5在磁盤(pán)文件中存有10個(gè)學(xué)生的數(shù)據(jù),要求讀取第1、3、5、7、9個(gè)學(xué)生數(shù)據(jù)并在屏幕上顯示。
編程思路:
(1)利用例11.4程序建立10個(gè)學(xué)生數(shù)據(jù)文件;
(2)按“二進(jìn)制只讀”方式打開(kāi)學(xué)生數(shù)據(jù)文件,準(zhǔn)備從文件中讀取數(shù)據(jù);
(3)將文件位置指針指向文件開(kāi)頭,讀取第1個(gè)學(xué)生數(shù)據(jù),輸出到屏幕上;
(4)分別使文件位置指針指向第3、5、7、9個(gè)學(xué)生數(shù)據(jù)區(qū)的開(kāi)始位置,讀取一個(gè)學(xué)生數(shù)據(jù),并輸出到屏幕上。
分析:本例是在例11.4程序建立的學(xué)生數(shù)據(jù)文件的基礎(chǔ)上,用“fopen("stu.dat","rb")”打開(kāi)文件,即以“二進(jìn)制只讀”方式打開(kāi)文件;采用步長(zhǎng)為2的循環(huán)和“i*sizeof(structstudent)”確定讀/寫(xiě)位置偏移量,使位置指針指向第1、3、5、7、9個(gè)學(xué)生數(shù)據(jù);把學(xué)生數(shù)據(jù)讀入到結(jié)構(gòu)體數(shù)組中,然后再按結(jié)構(gòu)體數(shù)組元素輸出。
11.5文件讀/寫(xiě)的出錯(cuò)檢測(cè)
怎樣檢測(cè)和處理數(shù)據(jù)文件讀/寫(xiě)中的出錯(cuò)信息?文件讀/寫(xiě)是和磁盤(pán)打交道,常會(huì)出現(xiàn)因磁盤(pán)的問(wèn)題導(dǎo)致操作失敗。因此需要檢測(cè)功能,及時(shí)識(shí)別問(wèn)題所在,以便調(diào)整操作或排除故障。文件讀/寫(xiě)函數(shù)具有出錯(cuò)檢測(cè)功能,通過(guò)返回值來(lái)識(shí)別。C語(yǔ)言系統(tǒng)還提供了專(zhuān)門(mén)的錯(cuò)誤檢測(cè)函數(shù)和出錯(cuò)標(biāo)志清除函數(shù)。
1.錯(cuò)誤檢測(cè)函數(shù)ferror
該函數(shù)調(diào)用的一般形式為
ferror(fp);
函數(shù)功能:檢測(cè)fp所指向的磁盤(pán)文件是否可正常讀/寫(xiě),如果不能正常讀/寫(xiě),返回一個(gè)非0值;能正常讀寫(xiě),返回值0。
執(zhí)行fopen函數(shù)調(diào)用時(shí),ferror函數(shù)的初始值自動(dòng)為0。應(yīng)注意,對(duì)同一文件每次調(diào)用輸入/輸出函數(shù),都會(huì)產(chǎn)生一個(gè)新的ferror函數(shù)值,因此,在調(diào)用一個(gè)輸入/輸出函數(shù)后,應(yīng)立即檢查ferror函數(shù)值,否則信息會(huì)丟失。
2.出錯(cuò)標(biāo)志清除函數(shù)clearerr
一旦文件出錯(cuò)一次,出錯(cuò)標(biāo)志就一直保留,使后續(xù)的輸入/輸出無(wú)法正常進(jìn)行。因此,應(yīng)及時(shí)清除出錯(cuò)標(biāo)志。該函數(shù)調(diào)用的一般形式為
clearerr(fp);
函數(shù)功能:將fp所指向的文件出錯(cuò)標(biāo)志置為0。
實(shí)操訓(xùn)練
實(shí)訓(xùn)任務(wù)十一學(xué)習(xí)程序與數(shù)據(jù)文件交互的程序設(shè)計(jì)方法實(shí)訓(xùn)項(xiàng)目1建立學(xué)生班級(jí)成績(jī)表數(shù)據(jù)文件,成績(jī)表式樣如表11.3所示,實(shí)現(xiàn)以下功能:
(1)從鍵盤(pán)輸入學(xué)生數(shù)據(jù),存入學(xué)生結(jié)構(gòu)體數(shù)組中。
(2)求每個(gè)學(xué)生的平均成績(jī),存到學(xué)生結(jié)構(gòu)體平均分字段中。
(3)建立數(shù)據(jù)文件,存儲(chǔ)學(xué)生成績(jī)表數(shù)據(jù)。
(4)輸出數(shù)據(jù)文件的學(xué)生成績(jī)表。
輸入/輸出界面可參照?qǐng)D11.2所示。圖11.2實(shí)訓(xùn)項(xiàng)目1界面式樣
實(shí)訓(xùn)指導(dǎo)
1.設(shè)計(jì)程序
(1)根據(jù)學(xué)生成績(jī)表式樣定義結(jié)構(gòu)體類(lèi)型及數(shù)組,同時(shí)定義文件指針,將其定義為全局?jǐn)?shù)據(jù)對(duì)象。
(2)從鍵盤(pán)輸入學(xué)生成績(jī)表數(shù)據(jù),存入結(jié)構(gòu)體數(shù)組中,可用一個(gè)函數(shù)來(lái)實(shí)現(xiàn)。函數(shù)形參設(shè)置為結(jié)構(gòu)體數(shù)組,循環(huán)一次輸入一條學(xué)生記錄,在循環(huán)中嵌套內(nèi)循環(huán),依次實(shí)現(xiàn)每門(mén)課成績(jī)輸入。輸入的數(shù)據(jù)存入學(xué)生結(jié)構(gòu)體對(duì)應(yīng)字段中。
(3)計(jì)算每個(gè)學(xué)生的平均成績(jī),可用一個(gè)函數(shù)來(lái)實(shí)現(xiàn)。函數(shù)形參設(shè)置為結(jié)構(gòu)體數(shù)組,用雙重循環(huán)依次實(shí)現(xiàn)每個(gè)學(xué)生各科目成績(jī)求和,并計(jì)算出平均成績(jī),存入學(xué)生結(jié)構(gòu)體的平均分字段中。
(4)創(chuàng)建學(xué)生成績(jī)表數(shù)據(jù)文件,可用一個(gè)函數(shù)來(lái)實(shí)現(xiàn)。函數(shù)形參設(shè)置為文件指針(file*x),循環(huán)一次把一條學(xué)生記錄(結(jié)構(gòu)體數(shù)組的一個(gè)元素)寫(xiě)入指針?biāo)赶虻奈募小?/p>
(5)輸出數(shù)據(jù)文件中學(xué)生成績(jī)表數(shù)據(jù),可用兩個(gè)函數(shù)來(lái)實(shí)現(xiàn)。先設(shè)計(jì)結(jié)構(gòu)體數(shù)組的一個(gè)元素(一條學(xué)生記錄)輸出的函數(shù),形參設(shè)置為結(jié)構(gòu)體變量,依次按成員順序輸出,其中學(xué)生成績(jī)是數(shù)組,需用內(nèi)循環(huán)依次按科目輸出。再設(shè)計(jì)數(shù)據(jù)文件中的結(jié)構(gòu)體數(shù)組(全部學(xué)生記錄)輸出的函數(shù),函數(shù)形參設(shè)置為文件指針(file*x),用循環(huán)實(shí)現(xiàn)從文件讀取一條學(xué)生記錄,賦給結(jié)構(gòu)體數(shù)組元素,調(diào)用結(jié)構(gòu)體的一個(gè)元素的輸出函數(shù)。
(6)在主函數(shù)中定義指針,并指向?qū)W生結(jié)構(gòu)體數(shù)組,依次調(diào)用輸入、求平均值、建立數(shù)據(jù)文件、輸出數(shù)據(jù)文件數(shù)據(jù)的函數(shù)。調(diào)用函數(shù)前應(yīng)正確設(shè)置實(shí)參。調(diào)用輸入和求平均值函數(shù)時(shí),實(shí)參是學(xué)生結(jié)構(gòu)體指針;調(diào)用建立數(shù)據(jù)文件函數(shù)和輸出數(shù)據(jù)文件數(shù)據(jù)函數(shù)前,應(yīng)打開(kāi)文件,文件指針作實(shí)參。
2.調(diào)試運(yùn)行程序
(1)從鍵盤(pán)輸入班級(jí)學(xué)生成績(jī)表數(shù)據(jù),檢測(cè)結(jié)果是否正確。
(2)在源文件目錄下,查看所建立的學(xué)生數(shù)據(jù)文件。
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 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ì)用戶上傳內(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024網(wǎng)絡(luò)編輯師考試應(yīng)考指南與試題及答案
- 深入討論風(fēng)險(xiǎn)管理的試題及答案
- 2025年銀行從業(yè)資格證常見(jiàn)題型試題及答案
- 畜牧師職稱(chēng)考試邊學(xué)邊練的必要性及試題及答案
- 理財(cái)工具的選擇與使用試題及答案
- 畜牧師職稱(chēng)考試綜合試題及答案匯編
- 精益求精2025年特許金融分析師考試試題及答案
- 畜牧師職稱(chēng)考試反思與總結(jié)試題及答案
- 實(shí)驗(yàn)研究2025年特許金融分析師考試試題及答案
- 2025年國(guó)際金融理財(cái)師考試知識(shí)傳承試題及答案
- 數(shù)字經(jīng)濟(jì)學(xué)試題答案
- 專(zhuān)題13 統(tǒng)計(jì)與概率-【好題匯編】五年(2020-2024)高考數(shù)學(xué)真題分類(lèi)匯編(含答案解析)
- 國(guó)家開(kāi)放大學(xué)本科(非英語(yǔ)專(zhuān)業(yè))學(xué)士學(xué)位英語(yǔ)統(tǒng)一考試樣題
- GB/T 44273-2024水力發(fā)電工程運(yùn)行管理規(guī)范
- 城軌行車(chē)課程設(shè)計(jì)
- 2024年南京市中考?xì)v史試題及答案
- 2024羽毛球教案36課時(shí)
- A類(lèi)供應(yīng)商績(jī)效評(píng)價(jià)表
- 攝影攝像知識(shí)競(jìng)賽考試題庫(kù)500題(含答案)
- 2024至2030年中國(guó)丹參行業(yè)市場(chǎng)發(fā)展監(jiān)測(cè)及投資潛力預(yù)測(cè)報(bào)告
- 2024招商引資協(xié)議書(shū)范本
評(píng)論
0/150
提交評(píng)論