




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第10章文件讀寫教學(xué)提示:存儲(chǔ)在變量和數(shù)組〔即內(nèi)存〕中的數(shù)據(jù)是臨時(shí)的,這些數(shù)據(jù)在程序運(yùn)行結(jié)束后會(huì)消失,而文件可以用來永久地保存大量的數(shù)據(jù)。如果有些數(shù)據(jù)需要反復(fù)使用或永久保存,應(yīng)該考慮使用文件來完成。教學(xué)要求:本章要掌握文件在讀寫之前必須翻開,讀寫結(jié)束必須關(guān)閉。文件可按只讀、只寫、讀寫、追加四種操作方式翻開,同時(shí)還必須指定文件的類型是二進(jìn)制文件還是文本文件。文件可按字節(jié),字符串,數(shù)據(jù)塊為單位讀寫,文件也可按指定的格式進(jìn)行讀寫。文件內(nèi)部的位置指針可指示當(dāng)前的讀寫位置,移動(dòng)該指針可以對(duì)文件實(shí)現(xiàn)隨機(jī)讀寫。10.1 文件概述與文件指針?biāo)^“文件〞是指一組相關(guān)數(shù)據(jù)的有序集合。我們?cè)谇皫渍轮幸褜掖谓佑|使用過文件,例如源程序文件、目標(biāo)文件、可執(zhí)行文件、庫文件(頭文件)等。10.1.1文件分類文件通常是駐留在外部介質(zhì)(如磁盤等)上的,在使用時(shí)才調(diào)入內(nèi)存中來。C語言把文件看作是由一個(gè)個(gè)字符〔字節(jié)〕的數(shù)據(jù)順序組成的。它把數(shù)據(jù)看作是連續(xù)的字符〔字節(jié)〕流,這樣它對(duì)文件的存取實(shí)際上是以字符〔字節(jié)〕為單位的。輸入輸出的數(shù)據(jù)流的開始和結(jié)束只受程序的控制而不受特定符號(hào)〔比方回車換行符〕的控制。也就是說,C語言在輸出數(shù)據(jù)到文件中時(shí),并不會(huì)自動(dòng)增加回車換行符以示結(jié)束,在輸入時(shí)也不會(huì)以讀入回車換行符作為數(shù)據(jù)的間隔。10.1.1文件分類從用戶的角度看,文件可分為普通文件和設(shè)備文件兩種。根據(jù)文件的存儲(chǔ)形式,可分為ASCII碼文件和二進(jìn)制文件兩種:(1)ASCII文件也稱為文本文件,這種文件在磁盤中存放時(shí)每個(gè)字符對(duì)應(yīng)一個(gè)字節(jié),用于存放對(duì)應(yīng)的ASCII碼。例如一個(gè)整型數(shù)據(jù)1234在文本文件中占4個(gè)字節(jié)。我們用Windows自帶的記事本軟件翻開該類型文件能讀懂文件中的內(nèi)容。(2)二進(jìn)制文件是按二進(jìn)制的編碼方式來存放文件的。例如一個(gè)整型數(shù)據(jù)230在二進(jìn)制文件中占2個(gè)字節(jié)。10.1.2文件類型指針在C語言中要使用文件,必須用一個(gè)指針變量指向一個(gè)文件,這個(gè)指針稱為文件指針。通過文件指針就可對(duì)它所指的文件進(jìn)行各種操作。定義文件指針的一般形式為:FILE*指針變量標(biāo)識(shí)符;其中FILE必須為大寫,它是在頭文件stdio.h中定義的一個(gè)結(jié)構(gòu)體,該結(jié)構(gòu)體中含有文件名、文件狀態(tài)和文件當(dāng)前位置等信息,我們編程時(shí)不必關(guān)心FILE結(jié)構(gòu)的細(xì)節(jié)。例如:FILE*fp;表示定義了一個(gè)名為fp的文件指針。如果變量fp已被正確賦值,那么可以根據(jù)結(jié)構(gòu)變量fp所提供的信息找到一個(gè)文件并實(shí)施對(duì)該文件的操作。習(xí)慣上把fp稱為指向一個(gè)文件的指針。10.2 文件的翻開與關(guān)閉使用文件必須遵循“先翻開,再對(duì)文件進(jìn)行讀寫操作,最后關(guān)閉文件〞的原那么。在C語言中,對(duì)文件的這些操作都可以由庫函數(shù)來完成,對(duì)用到的庫函數(shù)的聲明包含在文件stdio.h中,因此在編程中要操作文件時(shí),要使用頭文件包含命令#include“stdio.h〞。10.2.1 文件的翻開所謂翻開文件,實(shí)際上是獲得文件的各種有關(guān)信息,并使文件指針指向該文件,以便進(jìn)行下一步操作。C語言提供了函數(shù)fopen來翻開文件。其使用格式為:文件指針名=fopen(文件名,使用文件方式);其中,“文件指針名〞必須是已被說明為FILE類型的指針變量;“文件名〞是將被翻開的文件的文件名,通常是字符串常量或字符串?dāng)?shù)組〔注意路徑的分隔符應(yīng)使用“\\〞〕;“使用文件方式〞是指文件的類型和操作要求,是一個(gè)由一對(duì)雙引號(hào)括起來的字符串,共有12種,具體的符號(hào)表示和含義見表10-1。文件使用方式含義“rt”打開一個(gè)已經(jīng)存在的文本文件,只能讀取數(shù)據(jù)“wt”打開一個(gè)文本文件,只能寫入數(shù)據(jù)。若文件不存在,則自動(dòng)建立一個(gè)新文件接受寫入的數(shù)據(jù);若文件存在,則刪除文件中原有內(nèi)容,并接受寫入的數(shù)據(jù)(覆蓋)“a”打開一個(gè)已經(jīng)存在的文本文件,只能寫入數(shù)據(jù)并且追加在文件的尾部“r+”打開一個(gè)已經(jīng)存在的文本文件,可以讀取數(shù)據(jù),也可以寫入數(shù)據(jù)“w+”打開一個(gè)文本文件,可以讀取數(shù)據(jù),也可以寫入數(shù)據(jù)。若文件不存在,則自動(dòng)建立一個(gè)新文件接受寫入的數(shù)據(jù);若文件存在,則刪除文件中原有內(nèi)容,并接受寫入的數(shù)據(jù)(覆蓋)“a+”打開一個(gè)已經(jīng)存在的文本文件,可以讀取數(shù)據(jù),也可以寫入數(shù)據(jù)(追加在文件的尾部)“rb”打開一個(gè)已經(jīng)存在的二進(jìn)制文件,只能讀取數(shù)據(jù)“wb”打開一個(gè)二進(jìn)制文件,只能寫入數(shù)據(jù)。若文件不存在,則自動(dòng)建立一個(gè)新文件接受寫入的數(shù)據(jù);若文件存在,則刪除文件中原有內(nèi)容并接受寫入的數(shù)據(jù)(覆蓋)“ab”打開一個(gè)已經(jīng)存在的二進(jìn)制文件,只能寫入數(shù)據(jù)(追加在文件的尾部)“rb+”打開一個(gè)已經(jīng)存在的二進(jìn)制文件,可以讀取數(shù)據(jù),也可以寫入數(shù)據(jù)“wb+”打開一個(gè)二進(jìn)制文件,可以讀取數(shù)據(jù),也可以寫入數(shù)據(jù)。若文件不存在,則自動(dòng)建立一個(gè)新文件接受寫入的數(shù)據(jù);若文件存在,則刪除文件中原有內(nèi)容,并接受寫入的數(shù)據(jù)(覆蓋)“ab+”打開一個(gè)已經(jīng)存在的二進(jìn)制文件,可以讀取數(shù)據(jù),也可以寫入數(shù)據(jù)(追加在文件的尾部)fopen翻開文件例如:FILE*fpTa;fpTa=fopen("c:\\cprogram\\abc","rb");/*反斜線“\\〞中的第一個(gè)表示轉(zhuǎn)義字符*/其意義是翻開C驅(qū)動(dòng)器磁盤的cprogram子目錄下的文件abc,這是一個(gè)二進(jìn)制文件,只允許按二進(jìn)制方式進(jìn)行讀操作。又如:FILE*fp;fp=fopen("mytest1.txt","r");其意義是在當(dāng)前目錄下翻開文件mytest1.txt,只允許進(jìn)行“讀〞操作,并使fp指向該文件。10.2.2 文件關(guān)閉函數(shù)在使用完一個(gè)文件以后,應(yīng)該將該文件關(guān)閉,以防止它再被調(diào)用或喪失數(shù)據(jù)。“關(guān)閉〞就是使文件指針變量不再指向該文件,也就是文件指針變量與該文件“斷開〞,此后不能通過該指針對(duì)原來與其相聯(lián)系的文件進(jìn)行讀、寫操作〔除非再次翻開該文件,使文件指針變量重新指向該文件〕。fclose()函數(shù)用來關(guān)閉一個(gè)已經(jīng)由fopen()函數(shù)翻開的文件,正常完成關(guān)閉文件操作時(shí),fclose函數(shù)返回值為0,有錯(cuò)誤發(fā)生那么返回非零值。其調(diào)用的一般形式為:fclose(文件指針);例如:fclose(fp);10.3 文件位置指針的有關(guān)函數(shù)在文件內(nèi)部有一個(gè)位置指針,用來指向文件的當(dāng)前讀寫字節(jié)。在文件翻開時(shí),該位置指針總是指向文件的第一個(gè)字節(jié)。使用下面章節(jié)介紹的fgetc等函數(shù)對(duì)文件進(jìn)行讀寫后,該位置指針將自動(dòng)向后移動(dòng)。但文件指針和文件內(nèi)部的位置指針不是一回事。文件指針是指向整個(gè)文件的,須在程序中定義說明,只要不重新賦值,文件指針的值是不變的。文件內(nèi)部的位置指針用以指示文件內(nèi)部的當(dāng)前讀寫位置,每讀寫一次,該指針均自動(dòng)向后移動(dòng),它不需在程序中定義說明,而是由系統(tǒng)自動(dòng)設(shè)置的。順序讀寫和隨機(jī)讀寫文件的讀寫方式分為順序讀寫和隨機(jī)讀寫。(1)順序讀寫即讀寫文件只能從頭開始,順序讀寫各個(gè)數(shù)據(jù)。但在實(shí)際問題中常要求只讀寫文件中某一指定的局部,為了解決這個(gè)問題可移動(dòng)文件內(nèi)部的位置指針到需要讀寫的位置,再進(jìn)行讀寫,這種讀寫稱為隨機(jī)讀寫。(2)隨機(jī)讀寫可以通過利用系統(tǒng)函數(shù)去主動(dòng)移動(dòng)文件內(nèi)部的位置指針來實(shí)現(xiàn)。這樣的函數(shù)主要有兩個(gè),即rewind函數(shù)和fseek函數(shù)。實(shí)現(xiàn)隨機(jī)讀寫的關(guān)鍵是要按要求移動(dòng)位置指針,這稱為文件的定位。在移動(dòng)位置指針之后,即可用后面介紹的任一種讀寫函數(shù)進(jìn)行讀寫。由于一般是讀寫一個(gè)數(shù)據(jù)據(jù)塊,因此常用fread和fwrite函數(shù)。rewind函數(shù)rewind函數(shù)的功能是把文件內(nèi)部的位置指針移到文件首。其調(diào)用形式為:rewind(文件指針);“文件指針〞指向被移動(dòng)的文件。fseek函數(shù)fseek函數(shù)用來移動(dòng)文件內(nèi)部位置指針,其調(diào)用形式為:fseek(文件指針,位移量,起始點(diǎn));其中:“文件指針〞指向被移動(dòng)的文件。“位移量〞表示移動(dòng)的字節(jié)數(shù),要求位移量是long型數(shù)據(jù),以便在文件長(zhǎng)度大于64KB時(shí)不會(huì)出錯(cuò)。當(dāng)用常量表示位移量時(shí),要求加后綴“L〞。“起始點(diǎn)〞表示從何處開始計(jì)算位移量,規(guī)定的起始點(diǎn)有三種:文件首,當(dāng)前位置和文件尾。起始點(diǎn)表示符號(hào)數(shù)字表示文件首SEEK_SET0當(dāng)前位置SEEK_CUR1文件末尾SEEK_END2例如:fseek(fp,100L,0);/*將文件位置指針移到離文件頭100個(gè)字節(jié)處*/fseek(fp,20L,1);/*將文件位置指針從當(dāng)前位置后移20個(gè)字節(jié)的位置*/fseek(fp,-10L,SEEK_END);/*將文件位置指針從文件末尾前移10個(gè)字節(jié)的位置*/注意:fseek函數(shù)一般用于二進(jìn)制文件。在文本文件中由于要進(jìn)行轉(zhuǎn)換,往往計(jì)算的位置會(huì)出現(xiàn)錯(cuò)誤。
ftell函數(shù):用來得到流式文件中的當(dāng)前位置,用相對(duì)于文件開頭的位移量來表示。如返回-1L那么表示出錯(cuò)。例如:longa;a=ftell(fp);
文件結(jié)束檢測(cè)函數(shù)feof函數(shù)feof()判斷文件是否處于文件結(jié)束位置,如文件結(jié)束,那么返回值為1,否那么為0。其調(diào)用格式為:feof(文件指針);說明:文件結(jié)束標(biāo)志EOF(每個(gè)文件末有一結(jié)束標(biāo)志EOF,值為-1)只適用于判斷文本文件是否結(jié)束。而函數(shù)feof()那么對(duì)文本文件和二進(jìn)制文件都適用。10.4 讀寫文件
10.4.1 字符讀寫函數(shù)fgetc和fputc是以字符(字節(jié))為單位的讀寫函數(shù)。每次可從文件讀出或向文件寫入一個(gè)字符。字符輸入/出函數(shù)所處理的文件可以是文本文件,也可以是二進(jìn)制文件。
10.4.2 字符串讀寫函數(shù)fgets和fputs處理的文件一般是文本文件,讀寫的數(shù)據(jù)以字符串為單位。10.4.3 數(shù)據(jù)塊讀寫函數(shù)fread和fwtrite用于整塊數(shù)據(jù)的讀寫函數(shù)??捎脕碜x寫一組數(shù)據(jù),如一個(gè)數(shù)組、一個(gè)結(jié)構(gòu)變量的值等。10.4.4 格式化讀寫函數(shù)fscanf和fprintf與前面使用的scanf和printf函數(shù)的功能相似,都是格式化讀寫函數(shù)。兩者的區(qū)別在于fscanf函數(shù)和fprintf函數(shù)的讀寫對(duì)象不是鍵盤和顯示器,而是磁盤文件。
讀字符函數(shù)fgetcfgetc函數(shù)的功能是從指定的文件中讀取一個(gè)字符,函數(shù)調(diào)用的一般形式為:字符變量=fgetc(文件指針);例如:ch=fgetc(fp);其意義是從翻開的文件fp中讀取一個(gè)字符并送入字符變量ch中。對(duì)于fgetc函數(shù)的使用有以下幾點(diǎn)說明:(1)在fgetc函數(shù)調(diào)用中,讀取的文件必須是以讀或讀寫方式翻開的。(2)讀取字符的結(jié)果也可以不向字符變量賦值,例如fgetc(fp);但是讀出的字符不能保存。(3)文件內(nèi)部的位置指針在文件翻開時(shí)總是指向文件的第一個(gè)字節(jié)。使用fgetc函數(shù)后,該位置指針將向后移動(dòng)一個(gè)字節(jié)。因此可連續(xù)屢次使用fgetc函數(shù)來讀取多個(gè)字符?!纠?0.1】將C盤根目錄下的文本文件test1.txt的內(nèi)容在屏幕上輸出。#include<stdio.h>main(){FILE*fp;/*定義了文件指針fp*/charch;if((fp=fopen("c:\\test1.txt","r"))==NULL)/*以讀文本文件方式翻開并使fp指向該文件*/{printf("\nCannotopenfile,strikeanykeytoexit!");getchar();exit(1);}ch=fgetc(fp);/*先讀出一個(gè)字符,然后進(jìn)入循環(huán)*/while(ch!=EOF)/*判斷文件是否結(jié)束*/{putchar(ch);/*把該字符顯示在屏幕上*/ch=fgetc(fp);/*再讀入下一字符*/}fclose(fp);printf(“\n〞);}本例程序的功能是從文件中逐個(gè)讀取字符,并在屏幕上顯示。如翻開文件出錯(cuò),給出提示并退出程序。只要讀出的字符不是文件結(jié)束標(biāo)志EOF,就把該字符顯示在屏幕上,再讀入下一字符。每讀一次,文件內(nèi)部的位置指針向后移動(dòng)一個(gè)字符,文件結(jié)束時(shí),該指針指向EOF。執(zhí)行本程序?qū)@示文件c:\test1.txt的所有內(nèi)容。寫字符函數(shù)fputc()fputc函數(shù)的功能是把一個(gè)字符寫入指定的文件中,如寫入成功那么返回寫入的字符,否那么返回一個(gè)EOF,可用此來判斷寫入是否成功。函數(shù)調(diào)用形式為:fputc(字符量,文件指針);/*字符量是待寫入的字符常量或變量*/例如:fputc('x',fp);其意義是把字符‘x’寫入fp所指向的文件的位置指針的當(dāng)前位置中。每寫入一個(gè)字符,文件內(nèi)部位置指針向后移動(dòng)一個(gè)字節(jié)。
被寫入的文件可以用寫、讀寫、追加方式翻開?!纠?0.2】將從鍵盤上輸入的一些字符〔以“*〞作為結(jié)束〕寫入c盤根目錄下名為test2.txt的文本文件中。#include"stdio.h"main(){FILE*p; charch; if((p=fopen("c:\\test2.txt","w"))==NULL) {printf("Filecannotopen!\n"); exit(0); } printf("Pleaseinput,endinputwith*character:"); while((ch=getchar())!='*') fputc(ch,p); fclose(p); printf("Writeover!\n"); }程序運(yùn)行結(jié)束后,可以在c盤根目錄下翻開test2.txt查看其內(nèi)容。思考一下,如果在寫入完畢后想馬上把剛剛輸入的內(nèi)容打印在屏幕上該如何實(shí)現(xiàn)?字符串輸入/出函數(shù)字符串輸入/出函數(shù)所處理的文件一般是文本文件,讀寫的數(shù)據(jù)以字符串為單位。1. 讀字符串函數(shù)fgets功能是從指定的文件中讀一個(gè)字符串到字符數(shù)組中.函數(shù)調(diào)用的形式為:fgets(字符數(shù)組名,n,文件指針);其中n是一個(gè)正整數(shù)。該函數(shù)表示從文件中讀出n-1個(gè)字符〔如在讀滿n-1個(gè)字符之前就遇到了換行符或EOF,那么讀出提前結(jié)束〕,并在讀取的最后一個(gè)字符后加上串結(jié)束標(biāo)志'\0'。fgets函數(shù)的返回值是字符數(shù)組的首地址。讀取字符串后文件位置指針也自動(dòng)后移假設(shè)干個(gè)位置。例如:fgets(str,n,fp);意義是從fp所指的文件中讀出n-1個(gè)字符送入字符數(shù)組str中?!纠?0.3】從test2.txt文件中讀入8個(gè)字符組成一個(gè)字符串。#include<stdio.h>main(){FILE*fp;chararr[20];if((fp=fopen("c:\\test2.txt","r"))==NULL){printf("\nCannotopenfile,strikeanykeyexit!");getchar();exit(1);}fgets(arr,9,fp);printf("\n%s\n",arr);fclose(fp);}本例定義了一個(gè)字符數(shù)組str共20個(gè)字節(jié),在以讀文本文件方式翻開文件string后,從中讀出8個(gè)字符送入str數(shù)組,在第9個(gè)數(shù)組元素str[8]內(nèi)加上'\0',然后在屏幕上顯示輸出str數(shù)組存放的字符串。輸出的八個(gè)字符正是例10.2的前八個(gè)字符。2. 寫字符串函數(shù)fputsfputs函數(shù)的功能是向指定的文件寫入一個(gè)字符串〔不寫入字符串結(jié)束標(biāo)記'\0'〕,當(dāng)成功寫入一個(gè)字符串后,文件的位置指針會(huì)自動(dòng)后移,函數(shù)返回值為0;否那么,返回EOF〔符號(hào)常量,其值為-1〕。其調(diào)用形式為:fputs(字符串,文件指針);其中字符串可以是字符串常量,也可以是字符數(shù)組名或指針變量。例如:fputs(“a1b2〞,fp)是把字符串“a1b2〞寫入fp所指的文件之中?!纠?0.4】在文件test2.txt中追加一個(gè)不超過20個(gè)字符的字符串。#include<stdio.h>main(){FILE*fp;charch,st[21];intcount;if((fp=fopen("c:\\test2.txt","a+"))==NULL){printf("Cannotopenfilestrikeanykeyexit!");getchar();exit(1);}printf("inputastring:\n");gets(st);/*輸入不超過20個(gè)字符的字符串暫放入數(shù)組st中*/fputs(st,fp);rewind(fp);/*文件內(nèi)部位置指針移到文件的開始位置*/printf(“\nAllofthisfileis:\n〞);ch=fgetc(fp);while(ch!=EOF){putchar(ch);ch=fgetc(fp);}printf("\n");fclose(fp);}本例要求在test2.txt文件末添加一個(gè)字符串,因此,在程序第7行以追加讀寫文本文件的方式翻開文件test2.txt。然后輸入字符串暫放入數(shù)組st中,并用fputs函數(shù)把該串寫入文件test2.txt。后在程序中用rewind函數(shù)把文件內(nèi)部位置指針移到文件首,再進(jìn)入循環(huán)逐個(gè)顯示當(dāng)前文件中的全部?jī)?nèi)容。要注意用scanf(“%s〞,st)和gets(st)輸入字符串時(shí)的不同。思考:如果不用EOF,而是用feof()來判斷文件結(jié)束,上述陰影局部程序該如何改寫?數(shù)據(jù)塊讀寫函數(shù)fread和fwtriteC語言還提供了用于整塊數(shù)據(jù)的讀寫函數(shù)。可用來讀寫一組數(shù)據(jù),如一個(gè)數(shù)組、一個(gè)結(jié)構(gòu)變量的值等。讀數(shù)據(jù)塊函數(shù)調(diào)用的一般形式為:fread(buffer,size,count,fp);寫數(shù)據(jù)塊函數(shù)調(diào)用的一般形式為:fwrite(buffer,size,count,fp);其中:
size表示每個(gè)數(shù)據(jù)塊的字節(jié)數(shù)。
count表示要讀寫的數(shù)據(jù)塊塊數(shù)。fp表示文件指針。buffer是一個(gè)指針。
fread(buffer,size,count,fp)的功能是從fp所指向文件的位置指針的當(dāng)前位置讀取count塊數(shù)據(jù)〔每個(gè)數(shù)據(jù)所占的字節(jié)數(shù)為size〕,共組成count塊長(zhǎng)度為size的數(shù)據(jù)存入butter所指定的內(nèi)存空間中,當(dāng)正確的讀取了count塊數(shù)據(jù)后,文件內(nèi)部指針會(huì)自動(dòng)后移count*size個(gè)字節(jié)的位置,假設(shè)數(shù)據(jù)存入正確,那么返回count值,否那么返回NULL〔符號(hào)常量,其值為0〕。例如:fread(fa,4,5,fp);其意義是從fp所指的文件中,每次讀4個(gè)字節(jié)(一個(gè)實(shí)數(shù))送入實(shí)型數(shù)組fa中,連續(xù)讀5次,即讀5個(gè)實(shí)數(shù)到fa中。fwrite(buffer,size,count,fp)表示將從buffer起始地址的count塊數(shù)據(jù)〔每塊數(shù)據(jù)的字節(jié)數(shù)為size〕寫入到fp所指向的文件中,當(dāng)正確的寫入count塊數(shù)據(jù)后,文件位置指針會(huì)自動(dòng)后移count*size個(gè)字節(jié)的位置。假設(shè)數(shù)據(jù)寫入正確,那么返回count值;否那么返回NULL〔符號(hào)常量,其值為0〕?!纠?0.5】從鍵盤上輸入10個(gè)整數(shù),并把這些整數(shù)寫入c:盤根目錄下名為test3.dat的二進(jìn)制文件中。#include"stdio.h"main(){FILE*fp; intdata[10],i; if((fp=fopen("c:\\test3.dat","wb"))==NULL) {printf("Filecannotopen!\n"); exit(0); } printf(“Inputtenintegers:〞); for(i=0;i<10;i++) scanf("%d",&data[i]); fwrite(data,sizeof(int),10,fp); fclose(fp); printf(“Writeover!\n〞);}【例10.6】
從c:盤根目錄下名為test3.dat的二進(jìn)制文件中讀取10個(gè)整數(shù),要求先讀取第6~10個(gè)整數(shù),再讀取第1~5個(gè)整數(shù)。并把它們輸出到屏幕上顯示。#include"stdio.h"main(){FILE*fp; intdata[10],i; if((fp=fopen("c:\\test3.dat","rb"))==NULL) {printf("Filecannotopen!\n"); exit(0); }fseek(fp,5L*sizeof(int),0);/*先把文件位置指針后移*/
fread(data,sizeof(int),5,fp);/*先讀取第6~10個(gè)整數(shù)放入data[0]~data[4]*/ rewind(fp);/*把文件位置指針移到文件開始*/
fread(data+5,sizeof(int),5,fp);/*再讀取第1~5個(gè)整數(shù)放入data[5]~data[9]*/ fclose(fp); for(i=0;i<10;i++) printf("%5d",data[i]);}
【例10.7】從鍵盤輸入三個(gè)學(xué)生數(shù)據(jù),寫入一個(gè)文件中,再讀出這兩個(gè)學(xué)生的數(shù)據(jù)顯示在屏幕上。#include<stdio.h>structstu{charname[20];intnum;intage;charaddr[30];}boya[3],boyb[3],*pp,*qq;main(){FILE*fp;inti;pp=boya;qq=boyb;if((fp=fopen("c:\\studata","wb+"))==NULL){printf("Cannotopenfilestrikeanykeyexit!");getchar();exit(1);}
for(i=0;i<3;i++,pp++){ printf("inputnamenumageaddr:\n"); scanf("%s%d%d%s",pp->name,&pp->num,&pp->age,pp->addr);}pp=boya;fwrite(pp,sizeof(structstu),3,fp);rewind(fp);fread(qq,sizeof(structstu),3,fp);fclose(fp);printf("\n\nname\tnumberageaddr\n");for(i=0;i<3;i++,qq++) printf("%s\t%5d%7d%s\n",qq->name,qq->num,qq->age,qq->addr);}
本例程序定義了一個(gè)結(jié)構(gòu)stu,說明了兩個(gè)結(jié)構(gòu)數(shù)組boya和boyb以及兩個(gè)結(jié)構(gòu)指針變量pp和qq。pp指向boya,qq指向boyb。程序首先以讀寫方式翻開二進(jìn)制文件“studata〞,輸入三個(gè)學(xué)生數(shù)據(jù)之后,寫入該文件中。然后把文件內(nèi)部位置指針移到文件首,讀出三塊學(xué)生數(shù)據(jù)后,在屏幕上顯示。格式化讀寫函數(shù)fscanf和fprintffscanf函數(shù),fprintf函數(shù)與前面使用的scanf和printf函數(shù)的功能相似,都是格式化讀寫函數(shù)。兩者的區(qū)別在于fscanf函數(shù)和fprintf函數(shù)的讀寫對(duì)象不是鍵盤和顯示器,而是磁盤文件。這兩個(gè)函數(shù)的調(diào)用格式為:fscanf(文件指針,格式字符串,輸入表列);fprintf(文件指針,格式字符串,輸出表列);例如:
fscanf(fp,"%d%s",&i,s);fprintf(fp,"%d%c",j,ch);用fscanf和fprintf函數(shù)也可以完成例10.7的問題。修改后的程序如例10.8所示。
【例10.8】用fscanf和fprintf函數(shù)解決例10.7的問題。#include<stdio.h>structstu{charname[20];intnum;intage;charaddr[30];}boya[3],boyb[3],*pp,*qq;main(){FILE*fp;inti;pp=boya;qq=boyb;if((fp=fopen("c:\\studata","wb+"))==NULL){printf("Can’topenfilestrikeanykeyexit!");getch();exit(1);}printf("\ninputdata\n");for(i=0;i<3;i++,pp++)scanf("%s%d%d%s",pp->name,&pp->num,&pp->age,pp->addr);pp=boya;for(i=0;i<3;i++,pp++)fprintf(fp,"%s%d%d%s\n",pp->name,pp->num,pp->age,pp->addr);rewind(fp);for(i=0;i<3;i++,qq++)fscanf(fp,"%s%d%d%s\n",qq->name,&qq->num,&qq->age,qq->addr);printf("\n\nname\tnumberageaddr\n");qq=boyb;for(i=0;i<3;i++,qq++)printf("%s\t%5d%7d%s\n",qq->name,qq->num,qq->age,qq->addr);fclose(fp);}
本程序中fscanf和fprintf函數(shù)每次只能讀寫一個(gè)結(jié)構(gòu)體數(shù)組元素,因此采用了循環(huán)語句來讀寫全部數(shù)組元素。
還要注意指針變量pp,qq。由于循環(huán)改變了它們的值,因此在程序中分別對(duì)它們重新賦予了數(shù)組的首地址。
【例10.9】把命令行參數(shù)中的前一個(gè)文件名標(biāo)識(shí)的文件,復(fù)制到后一個(gè)文件名標(biāo)識(shí)的文件中,如命令行中只有一個(gè)文件名那么把該文件寫到標(biāo)準(zhǔn)輸出文件(顯示器)中。#include<stdio.h>main(intargc,char*argv[]){FILE*fp1,*fp2;charch;if(argc==1)/*如命令行參數(shù)中沒有給出文件名,那么給出提示信息*/{printf("Havenotenterfilename,strikeanykeyexit");getchar();exit(0);}if((fp1=fopen(argv[1],"rt"))==NULL){printf("Cannotopen%s\n",argv[1]);getchar();exit(1);}…….if(argc==2)/*如果只給出一個(gè)文件名,那么使fp2指向標(biāo)準(zhǔn)輸出文件(即顯示器)*/fp2=stdout;elseif((fp2=fopen(argv[2],"wt+"))==NULL){printf("Cannotopen%s\n",argv[1]);getchar();exit(1);}while((ch=fgetc(fp1))!=EOF)/*用循環(huán)語句逐個(gè)讀出文件1中的字符再送到文件2中*/fputc(ch,fp2);fclose(fp1);fclose(fp2);}
本程序?yàn)閹?shù)的main函數(shù)。程序中定義了兩個(gè)文件指針fp1和fp2,分別指向命令行參數(shù)中給出的文件。如命令行參數(shù)中沒有給出文件名,那么給出提示信息。如果只給出一個(gè)文件名,那么使fp2指向標(biāo)準(zhǔn)輸出文件(即顯示器)。然后用循環(huán)語句逐個(gè)讀出文件1中的字符再送到文件2中。假設(shè)工
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 云南大學(xué)面試題庫:IT行業(yè)求職必 備技能與面試技巧
- 人工搬運(yùn)安全培訓(xùn)課件
- 2025年云南省低壓電工操作證理論考試練習(xí)題(附答案)
- 2025年醫(yī)技科醫(yī)療安全與法律法規(guī)培訓(xùn)試題(附答案)
- 2025年傳統(tǒng)食品工業(yè)化生產(chǎn)智能化改造對(duì)行業(yè)競(jìng)爭(zhēng)力的提升策略分析
- 但丁人文主義課件
- 山東啟思大聯(lián)考2025-2026學(xué)年高三上學(xué)期開學(xué)考試數(shù)學(xué)試題(解析版)
- 綠色金融債券市場(chǎng)發(fā)行監(jiān)管政策與投資風(fēng)險(xiǎn)研究報(bào)告
- 2025-2030工業(yè)鍋爐超低排放改造市場(chǎng)容量測(cè)算報(bào)告
- 2025-2030工業(yè)互聯(lián)網(wǎng)平臺(tái)商業(yè)模式與價(jià)值鏈優(yōu)化咨詢報(bào)告
- 智慧水利與水資源管理作業(yè)指導(dǎo)書
- 人教版高一英語必修一單詞表(帶音標(biāo)) mp3跟讀朗讀聽力下載
- 中國(guó)移動(dòng)家集客考試題庫(濃縮700題)
- 醫(yī)療器械產(chǎn)品生命周期管理-洞察分析
- T∕CFA 0308052-2019 鑄造綠色工藝規(guī)劃要求和評(píng)估 導(dǎo)則
- 中國(guó)古代文學(xué)史明代文學(xué)
- 《薄冰英語語法詳解》
- 律師事務(wù)所數(shù)據(jù)安全應(yīng)急預(yù)案
- 生涯規(guī)劃講座模板
- 男生形體課課件
- 餐廳轉(zhuǎn)包合同范本
評(píng)論
0/150
提交評(píng)論