




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第9章文件處理9.1C語言中的文件9.2文件類型指針9.3文件操作習題99.1C語言中的文件
C語言中的文件為流式文件,即把文件看做是一個有序的字符流。每個文件或者以文件結束標志結束,或者在特定的字節(jié)號處結束(這個特定的字節(jié)號登記在由系統維護和管理的數據結構中),如圖9-1所示。圖9-1由n個字符構成的字符流(c文件)當打開一個文件的時候,該文件就和某個流關聯起來。執(zhí)行程序會自動打開三個標準文件——標準輸入文件、標準輸出文件和標準錯誤文件以及與這三個文件相連的三種流——標準輸入流、標準輸出流和標準錯誤流。流是文件和數據之間通信的通道。例如,標準輸入流能使程序讀取來自鍵盤的數據,標準輸出流能使程序把數據輸出到屏幕上。從操作系統的角度看,任何和主機相連的輸入/輸出設備都是文件,這些文件稱為標準文件。根據它們在輸入/輸出時所起的不同作用,標準文件可分為標準輸入文件(如鍵盤)和標準輸出文件(如屏幕、打印機)。從數據的組織來看,文件又分為兩類:文本文件和二進制文件。文本文件又稱為ASCII文件,文件中的每個元素都是字符。例如源程序文件就是文本文件。二進制文件是把數據轉換成二進制形式后存儲起來的文件。在內存中,所有的文件都要以二進制形式存儲,因此二進制文件可以不經轉換直接和內存通信。對于文本文件來說,要把它存入內存,中間就有個轉換成二進制的過程,輸出時又要把二進制形式轉換成字符形式,因而會影響速度。但文本文件有一個長處,就是在輸出時能以字符形式顯示文件的原有內容,便于閱讀。對于二進制文件來說,因為它的每個字節(jié)并不和字符相對應,因而在DOS狀態(tài)下用type命令輸出時會出現亂碼。下面看一下這兩種文件的差別。例如對于數據30000,它的文件形式和內存形式之間的關系如圖9-2所示。圖9-2兩種文件形式與內存形式之間的關系我們還應該了解一下操作系統處理文件的方式。C語言目前使用的磁盤文件系統主要是“緩沖文件系統”。所謂緩沖文件系統,是指在程序的數據區(qū)和磁盤文件之間并不是直接通信的,而是通過緩沖區(qū)相聯系的。所謂緩沖區(qū),實際上也是內存中的一段空間。在輸入數據時,先把數據從磁盤讀到“輸入緩沖區(qū)”中,等輸入緩沖區(qū)已滿或強制清空時再把其中的數據送到數據區(qū)進行處理。處理后的數據要送入文件保存,但這也不是隨處理隨傳送的,而是先放到“輸出緩沖區(qū)”,等輸出緩沖區(qū)已滿或強制將其清空時再把其中的數據送到磁盤文件。也就是說,不一定每執(zhí)行一次輸入/輸出語句就實際訪問磁盤文件一次,而是多次讀/寫對應一次磁盤訪問。緩沖區(qū)的大小隨機器而異,且由系統自動設置,其大小一般為512字節(jié)或其整數倍。緩沖文件系統的示意圖如圖9-3所示。圖9-3緩沖文件系統的示意圖9.2文件類型指針文件指針在緩沖文件系統中處理磁盤文件時有重要的作用。要運行一個文件,必須知道與該文件有關的信息,比如文件名、文件狀態(tài)、文件當前的讀/寫位置、文件緩沖區(qū)的大小與位置等。這些信息被系統保存在一個結構體中,這個結構體中的信息組成了文件類型。系統為該類型起了個專用的名字:FILE。FILE類型的結構和操作系統有關,也就是說,該結構的成員隨系統對文件處理方式的不同而不同。TurboC系統的文件結構類型為:typedefstruct{intlevel; /*緩沖區(qū)被占用的程度*/unsignedflags; /*文件狀態(tài)標記*/charfd: /*文件描述符*/unsignedcharhold; /*如無緩沖區(qū),則不讀取字符*/intbsize; /*緩沖區(qū)大小*/unsignedchar*buffer; /*文件緩沖區(qū)指針*/unsignedchar*curp; /*文件定位指針*/unsignedistemp; /*暫時文件指示器*/shorttoken; /*用于有效性檢查*/}FILE;
C語言程序要求,在對一個文件進行處理時,需首先定義一個FILE類型的指針,即建立一個FILE類型的指針變量,該指針變量用于指向系統內存中的一個FILE類型的結構體(即文件信息區(qū)),結構體中保存著當前處理文件的相關信息。文件指針的定義形式為:
FILE*〈文件指針名〉例如:
FILE*fp1,*fp2,*fp[3];則文件指針fp1和fp2可以指向某個文件結構體而訪問該文件,文件指針數組fp中有3個文件的信息。9.3文件操作文件操作包括文件的打開與關閉、輸入與輸出、定位、文件錯誤檢測及處理等。9.3.1文件的打開與關閉文件在使用之前必須打開,處理完之后必須關閉。
1.文件的打開文件的打開是通過調用fopen函數來實現的,其格式為:
〈文件指針〉=fopen(〈文件名〉,〈打開方式〉);其中:〈文件指針〉即類型為FILE的指針變量;〈文件名〉為DOS文件名,是一個字符串;〈打開方式〉也是個字符串,指出文件打開的目的。如:
FILE*fp;fp=fopen(″f1.txt″,″r″);說明把文件f1.txt以讀(r)的方式打開,函數的返回值是指向該被讀文件的指針。該指針由指針變量fp接收,于是fp就指向了f1.txt文件的信息區(qū)(FILE類型結構體),也可以說指向了f1.txt文件,以后對fp的操作即為對該文件的操作。如果要打開的文件不在當前目錄下,則應該帶上路徑。例如:如果文件data.dat處在D盤的temp目錄下,則應寫為:
fp=fopen(″D:\\temp\\data.dat″,″r″);其中的文件名是以字符串的形式出現的。在C語言中,字符串內“\\”代表一個“\”字符,故路徑中的反斜杠分隔符雙寫。文件的打開方式列于表9-1中,其中列出了各種文件的打開方式,隱含的是打開ASCII文件。如果打開的是二進制文件,則增加一個字符b(binary)。其他字符的含義為:r代表read,用于讀;w代表write,用于寫;a代表append,用于追加。
說明:①凡是打開方式字符串中含有字符“r”的,所打開的文件必須是已存在的文件,對不存在的文件不能打開讀。②凡是打開方式中帶有“w”字符的,所打開的文件可以是已經存在的,也可以是尚不存在的。若不存在時,則先要建立一個新文件,然后在里面寫內容;若文件已經存在,則會把原文件的內容覆蓋掉,寫入新的內容。③凡含有字符“a”的,以追加方式打開的文件也可以不存在。若不存在,則建立一個新文件,然后再追加;若已存在,則在文件的尾部追加。④以“r+”和“w+”方式打開的文件都是既可用于讀,又可用于寫的。其差別是,以“w+”方式打開的是一個新文件,應先寫入內容,然后可以讀。⑤在打開文件的操作中有可能出現故障,如當文件所在的磁盤未準備好時,不能把文件打開,這時打開文件函數fopen就返回NULL值。因此,一般在進行了打開文件的操作后,應立即檢查一下打開操作是否成功。如已成功打開,則可繼續(xù)進行;如果打開失敗,則應顯示提示信息,并用exit()函數強制關閉所有文件,結束程序運行并返回到操作系統狀態(tài)。這個過程常用的模式是:
if((fp=fopen(〈文件名〉,〈打開方式〉))==NULL){printf(″Openfail\n″); /*顯示打開失敗*/exit(0); /*結束程序*/}
(6)有三個和標準輸入/輸出流對應的設備文件不需用戶打開,在執(zhí)行程序時,系統自動將它們打開。這三個文件是標準輸入文件、標準輸出文件和標準出錯文件,指向它們的文件指針分別是stdin、stdout和stderr。
2.文件的關閉文件使用后必須及時關閉,以保護其中的數據。關閉就是使文件指針不再指向該文件,它可以再去指向其他文件。關閉文件的操作還有一個作用是清除緩沖區(qū)。在文件處理的最后,緩沖區(qū)中可能尚有一些數據,關閉操作首先把這些數據送入磁盤文件,然后再釋放文件指針。因此,如果不關閉文件,則留在緩沖區(qū)中的數據就會丟失。關閉文件用fclose函數,其格式為:
fclose(〈文件指針名〉);如:
fclose(fp);則使fp不再指向剛才它所指的文件。如果關閉成功,則fclose函數的返回值是0;如果關閉失敗,則返回值是EOF(即-1)。9.3.2文件的輸入與輸出文件的輸入/輸出操作一般是按以下步驟進行的:
(1)用fopen函數打開文件。
(2)對文件進行讀/寫操作。
(3)用fclose函數關閉文件。對已打開的文件的輸入/輸出操作是通過文件指針進行的,實際上它們是由一些標準的讀/寫函數完成的。所謂文件的輸入,是指用一些具有讀功能的函數把磁盤文件中的數據讀入內存;所謂文件的輸出,是指用一些具有寫功能的函數把內存中的數據寫入磁盤文件。
1.文件的字符輸入函數fgetc和字符輸出函數fputc
1)fgetc函數
fgetc函數的調用格式為:
〈字符變量〉=fgetc(〈文件指針〉);功能:從〈文件指針〉所指的文件中讀入一個字符賦給〈字符變量〉(在內存中)。例如:
charc;FILE*fp;fp=fopen(″filein.txt″,″r″);if(fp!=NULL) c=fgetc(fp);文件讀/寫過程中,有一個文件定位指針時刻指向正在操作的位置,它會隨著讀/寫操作的進行而變化。fgetc函數就把文件定位指針當前位置處的字符讀出,并將其轉換成ASCII碼值,返回給字符變量。如果讀取失敗或到文件末尾,fgetc函數將返回一個文件結束標志EOF(即-1)。EOF不是可顯示字符,不能在屏幕上出現。字符的ASCII碼不可能為-1,故可將EOF視作文本文件的結束標志。但對二進制文件則不然,因為二進制文件某個字節(jié)中的數據可能是-1,如把-1作為文件結束標志,則會失去-1之后的所有數據,所以ANSIC提供了一個判斷文件是否結束的函數feof,其參數為文件指針。如文件結束,則feof(fp)的值為1,否則feof(fp)的值為0。這個函數對于文本文件也適用。如果fp為標準輸入文件指針stdin,則fgetc函數的功能就是從鍵盤上輸入字符,這和getchar函數是一樣的,即
fgetc(stdin)=getchar()實際上,這個工作已在<stdio.h>頭文件中用宏定義的形式作了說明: #definegetchar()fgetc(stdin)
2)fputc函數設ch為字符類型,則其調用格式為:
fputc(ch,〈文件指針〉);功能:把字符ch(變量或常量)放入〈文件指針〉所指的文件中。如果操作失敗,則返回一個EOF。如果文件指針為標準輸出文件指針stdout,則有:
fputc(ch,stdout)=putchar(ch)這也在頭文件<stdio.h>中作了宏定義: #defineputchar(ch)fputc(ch,stdout)對標準輸入/輸出文件而言,用getchar()和putchar()更為簡單。
3)用字符輸入/輸出函數處理文件看下面的例子。
【例9-1】文本文件復制。把文件c:\f1.bat進行復制,新文件為a:\f2.bat。#include<stdio.h>main(){FILE*fp1,*fp2;charc;if(((fp1=fopen(″c:\\f1.bat″,″r″))==NULL)||((fp2=fopen(″a:\\f2.bat″,″w″))==NULL)){printf(″openfail\n″);exit(0);}while(!feof(fp1)){c=fgetc(fp1);fputc(c,fp2);}fclose(fp1);fclose(fp2);return0;}該程序是把c盤上的批處理文件拷貝到a盤上。c盤上的文件作為數據的提供者,以“r”方式打開;a盤上的文件作為數據接收者,以“w”方式打開。while(!feof(fp1))等價于while(feof(fp1)==0),即文件fp1未結束時執(zhí)行循環(huán)操作。
【例9-2】實現操作系統命令提示符下的文件連接功能,如命令
c:\>appendfile1file2實現把文件file1追加到文件file2的末尾。程序如下:#include<stdio.h>main(intargc,char*argv[]){FILE*fp1,*fp2;intc;if(argc!=3){printf(″USAGE:file1file2\n″);exit(0);}if(((fp1=fopen(argv[1],″r″))==NULL)||((fp2=fopen(argv[2],″a″))==NULL)){printf(″Openfail\n″);exit(0);}while((c=fgetc(fp1))!=EOF)
fputc(c,fp2);fclose(fp1);fclose(fp2);return0;}該程序中的main函數必須帶參數。文件fp1以讀方式打開。文件fp2以追加方式打開后,文件指針自動指向其末尾,后面進行的讀/寫操作是從fp1文件上一個個地讀字符,并一個個地放入fp2文件中,直到遇到文件結束符為止。將該程序進行編譯、連接后,如果將生成的可執(zhí)行文件取名為append,那么它就相當于一個DOS命令了。
2.文件的字符串輸入/輸出函數fgets()和fputs
1)fgets()函數
fgets函數的調用格式為:
fgets(str,n,fp);其中,str為指定的字符數組;n為包括“\0”字符在內的字符個數;fp為文件指針。功能:從fp所指文件中讀取n-1個字符(留一個字符給′\0′),并把它們放入str字符數組中。當滿足下列條件之一時,讀取結束:
(1)已經讀取了n-1個字符。
(2)當前讀到的字符為回車符。
3)已讀到文件的末尾。不管是以哪種情況結束,系統都會把空字符′\0′加到所讀字符串的最后,即使讀入的是回車符。例如,設讀取的字符串為“china〈CR〉”,則在內存緩沖區(qū)中的存儲形式為:由此可以看出,把fgets函數作用到標準輸入指針stdin之后,其功能和gets函數并不完全相同,即:
fgets(str,n,stdin)≠gets(str)因為在用gets函數時是把回車符轉換成空字符′\0′加在字符串尾部,而fgets函數是把讀入的回車符保存起來,另外再加一個′\0′符號。china<CR>\0
2)fputs函數
fputs函數的調用格式為:
fputs(str,fp);其中,fp為文件指針,str為一字符串,它可以是指向字符串的指針,也可以是字符數組名,還可以是字符串常量。功能:把指定的字符串放到指定的文件中。
fputs函數在將字符串寫入文件時,把字符串后的′\0′字符自動舍去。同樣有
fputs(str,stdout)≠puts(str)因為puts()函數是把字符串尾部的′\0′字符變成回車符輸出,而fputs函數則是舍去字符串末尾的′\0′字符。
fputs函數若輸出成功,則返回值為0;若輸出失敗,則返回值為EOF(即-1)。
【例9-3】fputs函數的應用。#include<stdio.h>main(){charstr[10];gets(str);puts(str);puts(str);putchar(′\n′);fputs(str,stdout);fputs(str,stdout);return0;}運行輸出:
very↙ /*輸入*/very /*兩個puts的輸出*/veryveryvery /*兩個fputs的輸出*/分析運行結果可以看出:輸入中的回車符變?yōu)椤洌?′附在最后;用puts函數輸出時遇到′\0′變?yōu)榛剀嚪麚Q行,因此有兩行“very”。在輸出第二個“very”并換行后又執(zhí)行putchar(′\n′),則又空出一行。當遇到fputs時,輸出“very”后不換行,則第二個“very”就在同一行輸出了。仍用上面的例子,如果把其中的gets(str)換成fgets(str,10,stdin),則執(zhí)行后的輸出結果是:
very↙ /*輸入*/very /*空1行*/very /*空兩行*/veryvery請分析為什么會出現這樣的結果。
【例9-4】將一個磁盤文件上的內容加上行序號顯示在屏幕上,并復制到另一個磁盤文件中。#include<stdio.h>
#include<stdlib.h>main(intargc,char*argv[]){charbuff[256];FILE*fp1,*fp2;intline;if(argc!=3){puts(″3parameters\n″);
exit(0);
}if(((fp1=fopen(argv[1],″r″))=NULL||((fp2=fopen(argv[2],″w″))=NULL)){printf(″Openfail\n″);
exit(0);
}line=1;while(fgets(buff,256,fp1)!=NULL){printf(″%3d:%s″,line++,buff);fputs(buff,fp2);}fclose(fp1);fclose(fp2);return0;
}函數fgets從fp1文件中輸入一行字符送入buff緩沖區(qū)中,然后用printf函數語句把它的行號與buff中的字符串送到顯示器顯示,又用fputs函數把該行送入文件fp2中。這是在DOS命令提示符下進行的操作,所以在把程序編譯、連接后,生成.exe文件,設文件名為fcopy,則在執(zhí)行
c:\>fcopyfile1.txtfile2.txt之后,file1中的內容既在屏幕上顯示,又被復制到文件file2中。
3.文件數據塊的輸入/輸出函數fread和fwrite
fgetc和fputc函數一次只能讀和寫一個字符,fgets和fputs函數一次只能讀和寫不能確定字符個數的一串字符。但是,在程序的應用中,我們常常需要能夠一次讀/寫有一定字符長度的數據,比如一個記錄等,為此C語言又提供了兩個這樣的讀/寫函數即fread和fwrite函數。
1)fread函數
fread函數調用的一般格式為:
fread(buf,size,count,fp);其中buf是一個指針,指向輸入數據在內存中的起始地址;size為要讀取的字節(jié)個數;count為要讀取多少個size字節(jié)的數據項;fp為指向由fopen打開的文件的指針。功能:從由fp指定的文件中讀取size*count個字節(jié)的數據,并把它放入由buf指定的內存中。當文件以二進制形式打開(即fp=fopen(″file1″,″rb″);)時,fread函數就可以用來讀取各種類型的數據信息。如:
fread(fbuf,sizeof(float),4,fp);則從由fp指定的文件中讀出4個大小為sizeof(float)的數據放入fbuf中,fbuf為一實型數組名,也是其第一個元素的地址。
fread函數的返回值:若讀取成功,則返回讀取的項數即count值;若讀取失敗,則返回-1。
2)fwrite函數
fwrite函數調用的格式為:
fwrite(buf,size,count,fp);其中,參數的個數和類型與fread函數完全一樣,只是它進行相反的操作。這里的buf是輸出數據在內存中存放的地址。功能:把buf中大小為size*count個字節(jié)的數據寫入由fp指定的文件中。如語句:
fwrite(ibuf,2,5,fp);是把整型數組中的5個整數寫入由fp指定的文件中。返回值:若輸出成功,則返回寫入文件中的數據項數;若輸出失敗,則返回-1。常常聯合使用fread和fwrite函數對二進制文件進行讀/寫。
【例9-5】從鍵盤錄入n個學生的準考證號、姓名、總分,把這些數據保存到磁盤文件kaosheng.lst中,然后再從磁盤文件中讀出并在屏幕上顯示出來。#include<stdio.h>
#defineN500structstudent{unsignedlongno;charname[15];floatscore;}stud[N];
typedefstructstudentSTU;voidsave(void);voidload(void);intm=0;main(){inti;printf(″Inputstudentnumberm:1≤m≤%d\n″,N);scanf(″%d″,&m);for(i=0;i<m;i++)scanf(″%lu%s%f″,&stud[i].no,stud[i].name,&stud[i].score);save();load();return0;}voidsave(void){FILE*fp;inti;if((fp=fopen(″A:\\kaosheng.lst″,″wb″))==NULL){printf(″Openfail\n″);exit(0);}for(i=0;i<m;i++)if(fwrite(&stud[i],sizeof(STU),1,fp)!=1){printf(″Filewriteerror!\n″);exit(0);}fclose(fp);
}voidload(void){inti;FILE*fp;if((fp=fopen(″A:\\kaosheng.lst″,″rb″))==NULL){printf(″Openfail\n″);exit(0);
}for(i=0;i<m;i++){if(fread(&stud[i],sizeof(STU),1,fp)!=1){printf(″Filereaderror\n″);exit(0);
}printf(″No:%lu\tName:%s\tscore:%f\n″,stud[i].no,stud[i].name,stud[i].score);}fclose(fp);
}在save和load函數中都是用if語句的條件判斷,即利用fwrite和fread函數成功執(zhí)行后返回寫入和讀出的數據塊的項數的特點來完成輸入/輸出工作的,這使程序顯得非常簡潔;另外使用typedef把一個長的結構體類型名structstudent簡稱為STU,這樣在程序中簡化了書寫。程序中預留出500個考生的位置,根據實際參加考試的人數決定數組實際使用的大小。用全局變量m來表示實際人數,它可在多個函數中使用。在主函數main中,首先執(zhí)行把信息從鍵盤輸入到內存的操作,即把m個考生的準考證號(準考證號很長,所以定義為無符號長整型,對其輸入/輸出時相應的控制符為“%lu”)、姓名和總分輸入到內存,然后調用save函數,將這些數據寫入以kaosheng.lst命名的磁盤文件中。fwrite函數一次將一個長度為sizeof(STU)(即結構體各分量長度之和:4+15+4=23)個字節(jié)的數據塊寫入kaosheng.lst文件中,共m個學生的數據。接著再調用load函數,從磁盤文件kaosheng.lst中讀出已存入的學生數據,并把它們顯示在屏幕上,形如:
No:03008942Name:Zhangyi598.5No:03008943Name:Wangyue632.5函數save和load的參數類型都是void,它們和主函數之間的信息傳遞不是通過參數,而是通過全局變量來實現的。我們考察一下數據從鍵盤輸入到屏幕輸出的整個過程中所發(fā)生的現象:由鍵盤輸入的是字符(文本文件),送入計算機內存時把回車、換行兩個字符轉換成一個換行符;從內存中以“wb”(二進制寫)方式輸出到磁盤文件,不需要轉換,是按內存的形式輸出到文件的;再以“rb”(二進制讀)方式把磁盤文件讀入內存中,也不需任何轉換,是按其原始形式進行輸入的;最后用printf函數將內存中的數據輸出到屏幕上,是將二進制文件轉換成文本文件,又把換行符轉換成回車、換行兩個字符。對同一個文件進行讀/寫操作時,必須以同一種組織方式打開,即都以文本格式打開或都以二進制格式打開。
fread和fwrite函數一般用于二進制文件的輸入/輸出,因為它是按指定大小存儲數據塊的,而數據塊都是由有效數據項組成的。從二進制文件中讀一個結構體信息時,能把結構體各個分量數據完整地讀進來。而如果從鍵盤上讀,如
fread(&stud[i],sizeof(STU),1,stdin);那么當你輸入的數據中含有空格時,如
0398772zhaori599則該函數就只輸入sizeof(STU)個字符到stud[i]中,其中包含空格等分隔符,這樣一來,各分量的數據可能就不是你所希望的了。
4.文件的格式化輸入/輸出函數fscanf和fprintf這兩個函數的調用格式分別是:
fscanf(〈文件指針〉,〈格式控制串〉,〈輸入列表〉);
fprintf(〈文件指針〉,〈格式控制串〉,〈輸出列表〉);它們的作用與scanf函數和printf函數幾乎一樣,差別就在于它們可以對任何文件進行輸入/輸出,而scanf和printf只對終端設備進行。因此使用fscanf和fprintf函數時應該帶一個文件指針。如
fscanf(fp,″%d%f″,&i,&x);表示從fp所指文件中讀入一個整數給i,讀入一個浮點數給x(這樣做要非常小心,必須先要知道磁盤上的數據是如何存儲的)。而
fprintf(fp,″%d%s″,i,″China″);則把整數i和字符串“China”寫入fp所指的文件中。當文件指針為stdin和stdout時,fscanf和fprintf的作用就與scanf和printf完全相同了,即
fscanf(stdin,″…″,…)=scanf(″…″,…)fprintf(stdout,″…″,…)=printf(″…″,…)用函數fscanf和fprintf對磁盤文件進行讀/寫的優(yōu)點是方便,容易理解;缺點是運行速度較慢,因為它們在輸入時要將ASCII碼轉換成二進制形式,輸出時又要將二進制形式轉換成ASCII碼字符。顯然,如果在磁盤文件與內存之間頻繁交換數據的情況下使用fscanf和fprintf,則程序的效率是很低的,此時最好采用數據塊輸入/輸出函數fread和fwrite。9.3.3文件的定位我們已經知道,C語言中的文件是流式文件,處理文件的方式是順序處理。文件一打開,就有一個定位指針指向規(guī)定的地方,隨著讀/寫的進行,定位指針自動向下移動。但在很多情況下需要改變這種順序讀/寫的方法,即能任意指定讀/寫位置,為此C語言又提供了相應的函數,主要有:返回文件定位指針當前位置的函數ftell()、重新把文件定位指針置于文件頭的函數rewind()和改變文件定位指針當前位置的函數fseek()。
1.ftell函數該函數的功能是返回文件定位指針的當前位置,即相對于文件頭的位移量(長整型),文件頭的位置定為0。函數的參數是文件指針。如果該函數運行不正常,則返回值為-1L,表示出錯。程序中可利用返回值來判斷函數調用是否出錯,如
i=ftell(fp);
if(i==-1L)printf(″ERROR\n″);當文件剛打開時,ftell返回值為0L。
2.rewind函數該函數的功能是把文件定位指針重新拉回到文件開頭,這在對文件進行多遍操作時非常有用,即不需要反復進行文件關閉與打開操作,只需調用rewind函數即可。其調用格式為:
rewind(fp);表示把fp所指文件的定位指針拉回到文件頭,不管它現在處于什么位置。
3.fseek函數該函數的功能是把文件定位指針設置到需要的地方。該函數的調用格式為:
fseek(〈文件指針〉,〈位移量〉,〈起始點〉);其中,〈位移量〉是長整型,長整型的標志是整型數據后加字符“L”;位移量可正可負,正代表向后(尾),負代表向前(頭);〈起始點〉即位移的參照點,共有三個,可以用名字,也可用相應的數字表示,具體情況如表9-2所示。例如:
fseek(fp,50L,0);/*定位于距文件頭50個字節(jié)處*/fseek(fp,-25L,1); /*定位于當前位置前25個字節(jié)處*/fseek(fp,-10L,2); /*定位于文件尾前10個字節(jié)處*/顯然當起始點在文件開頭時,位移量只能為正;當起始點在文件尾時,位移量只能為負。
【例9-6】設文件stu.txt中存有40名學生的信息,學號從1~40編號。將學生的信息按學號的奇偶分為兩組,分別加以輸出。#include<stdio.h>
#defineN40structstudent{intno;charname[15];floatscore;}stud[N];
typedefstructstudentSTU;main(){FILE*fp;inti,n;if((fp=fopen(″a:\\stu.txt″,″rb″)==NULL){printf(″Openfail\n″);exit(0);}printf(″Listoddno.students:\n″); if(N%2==0) n=N/2; else n=N/2+1; for(i=0;i<N/2;i++) {fseek(fp,2*i*sizeof(STU),0);if(fread(&stud[i],sizeof(STU),1,fp)!=1){printf(″Filereaderror!\n″);exit(0);}printf(″No:%d\tNAME:%s\tScore:%f\n″,
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年調查分析師考試試題及答案
- 人工智能技術研發(fā)經驗工作證明(5篇)
- 授權代表證明書及授權事項清單(8篇)
- 某中學圖書借閱統計分析制度
- 2025年電式混動車項目申請報告
- 網絡維護外包服務協議合同書
- 經濟學原理與經濟形勢分析題目
- 物聯網技術在智慧城市規(guī)劃中的應用協議
- 2025年注冊會計師考試《會計》財務報表分析解題思路與技巧試題
- 介紹我的日常用品作文9篇范文
- 2025年陜西、山西、青海、寧夏高考政治試卷真題(含答案解析)
- 3.21 明清時期的科技與文化 課件 2024-2025學年統編版七年級歷史下冊
- 出國培訓考試試題及答案
- 養(yǎng)老護理員四級考試題庫及答案
- 2024年中國中小企業(yè)融資發(fā)展報告
- 辦公室內控管理制度
- 2025年高二語文下學期期末考試語言文字運用專項練習含答案解析
- 2024-2025 學年八年級英語下學期期末模擬卷 (蘇州專用)原卷
- 安徽省宿州市碭山縣2023-2024學年八年級下學期期末數學試題
- 2024-2025 學年七年級英語下學期期末模擬卷 (深圳專用)原卷
- 子癇與重度子癇的護理
評論
0/150
提交評論