C語言第10章對文件的輸入輸出_第1頁
C語言第10章對文件的輸入輸出_第2頁
C語言第10章對文件的輸入輸出_第3頁
C語言第10章對文件的輸入輸出_第4頁
C語言第10章對文件的輸入輸出_第5頁
已閱讀5頁,還剩33頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

2/6/20231第10章對文件的輸入輸出文件:存儲在外部介質上數據的集合。操作系統是以文件為單位對數據進行管理的。與主機相聯的輸入輸出設備都看作是一個文件。C語言把文件看作是一個字符(字節)的序列。分為:ASCII文件(文本文件)、二進制文件。ASCII文件:每一個字節放一個ASCII代碼,代表一個字符。二進制文件:把數據按其在內存中的存儲形式輸出到磁盤上存放。0010011100010000001001110001000000110001001100000011000000110000001100002/6/20232第10章文件緩沖區文件系統:系統自動地在內存區為每一個正在使用的文件開辟一個緩沖區。非緩沖區文件系統:系統不自動開辟確定大小的緩沖區,而由程序為每個文件設定緩沖區。磁盤輸出輸出輸入輸入程序數據區輸出文件緩沖區輸入文件緩沖區2/6/20233文件類型指針typedef

struct{shortlevel;//緩沖區“滿”或“空”的程度unsignedflags;//文件狀態標志charfd;//文件描述符

unsignedcharhold;//如無緩沖區不讀取字符shortbsize;//緩沖區的大小unsignedchar*buffer;//數據緩沖區的位置unsignedchar*curp;//指針,當前的指向unsignedistemp;//臨時文件,指示器

shorttoken;//用于有效性檢查}FILE;levelflagsfdholdbsizebuffercurpistemptoken…………

文件打開函數fopen用來打開一個文件,其調用的一般形式為:文件指針名=fopen(文件名,使用文件方式);其中:“文件指針名”必須是被說明為FILE類型的指針變量;“文件名”是被打開文件的文件名;文件名通常是文件變量或文件數組;“使用文件方式”是指文件的類型和操作要求。文件的使用方式共有12種,表10.1給出了文本文件的符號和意義。10.2文件的打開與關閉

由于文件的打開與關閉都是利用系統函數來實現的,因此,在編寫有關文件的程序時,應該在其中包含“stdio.h”頭文件。

10.2.1文件的打開

2/6/20235文件的打開與關閉文件的打開(fopen

函數)FILE*fp;fp=fopen(文件名,使用文件方式);例如:fp=fopen("a1","r");文件名:參數為字符指針類型,實參為帶路徑的字符串。使用文件方式:參見表10.1。

"r"、"w"、"a"、"r+"、"w+"、"a+""rb"、"wb"、"ab"、……說明:"r"、"w"、"a"等打開文件的方式。打開文件的常規方式:if((fp=fopen("file1","r"))==NULL){printf("Cannotopenthisfile\n");exit(0);}文件中的回車換行符內存中的換行符。程序運行時,系統主動打開3個標準文件:stdin:終端輸入stdout:終端輸出stderr:標準出錯輸出文件使用方式代表的含義r打開一個已有的文本文件,只允許讀取數據w打開或建立一個文本文件,只允許寫入數據at打開一個已有的文本文件,并在文件末尾寫數據rt+打開一個已有的文本文件,允許讀和寫at+打開一個已有的文本文件,允許讀或在文件末追加數據wt+打開或建立一個文本文件,允許讀寫表10-1文本文件的符號及其含義

以上六種方式是針對“文本文件”類型

文件使用方式代表的含義rb打開一個已存在的二進制文件,只允許讀數據

wb打開或建立一個二進制文件,只允許寫數據

ab

打開一個二進制文件,并在文件末尾追加數據

rb+打開一個二進制文件,允許讀和寫

wb+打開或建立一個二進制文件,允許讀和寫

ab+打開一個二進制文件,允許讀或在文件末追加數據

表10-2二進制文件的符號及其含義

可以看出,上面兩個表的作用基本上是相同的,唯一的區別是表10-2增加了一個表示二進制的字符“b”。其中,文件使用方式由r、w、a、t、b和+六個字符組成,各字符的含義如表所示。

字母代表含義rread讀取數據wwrite寫入數據aapend追加數據ttext文本文件,可省略不寫bbinary二進制文件+可讀可寫表10-3文件使用方式中的字符及其含義

1.程序中凡是用“r”打開一個文件時,表明該文件必須已經存在,且只能從該文件讀出數據。

2.用“w”打開的文件也只能向該文件寫入數據。若打開的文件不存在,則按照指定的文件名建立該文件,若打開的文件已經存在,則將該文件刪除,重建一個新文件。使用時要特別注意這一點。

3.如果要向一個已經存在的文件后面追加新的信息,那只能用“a”方式打開文件。但此時該文件必須是存在的,否則將會出錯。

對上表做以下補充說明:4.在打開一個文件之前,應該定義文件型指針,以便接收函數fopen返回的地址。如果出錯,fopen將返回一個空指針NULL。在程序中可以用這一信息來判別是否完成打開文件的工作,并做相應的處理。例如:

if((fp=fopen(“file1”,”rb”))==NULL){

printf(“\nerroronopenfile1”);

getch();exit(1);}

該程序段表示:如果返回的指針為空,則不能打開當前目錄下的文件“file1”,同時給出錯誤提示信息“erroronopenfile1”。程序中的getch()函數的功能是從鍵盤輸入一個字符,該字符不在屏幕上顯示。其實getch()在這里的作用是停留等待,只有當用戶從鍵盤敲任意鍵時,程序才繼續執行,我們可以利用這個等待時間來閱讀出錯提示,找到錯誤原因。當敲任意鍵后,執行語句“exit(1);”,從而退出程序。文件一旦使用完畢,應使用關閉文件函數fclose把文件關閉,以避免文件數據丟失等情況的發生。

fclose函數調用的一般形式為:

fclose(FILE*fp);其中,參數fp是文件型指針,通過fopen()函數已經獲得,它指向某個打開的文件。例如:fclose(fp);

上述語句的含義是關閉fp所指向的文件,同時自動釋放分配給文件的內存緩沖區。當正常完成關閉文件的操作時,fclose函數的返回值為0,表示已正確關閉指定的文件;如返回非0值則表示有錯誤發生。

10.2.2文件的關閉

【例10.2】文件的打開與關閉應用舉例。

#include<stdio.h> voidmain() { FILE*fp;/*定義一個文件指針*/

if((fp=fopen("C:\\STUDENT\\ch01_01\\ch01_01.c","rb"))==NULL) {

printf("filecannotopen!\n"); exit(1); } else

printf("Thefilesucceedopen!\n");

fclose(fp); }

說明:在書寫時,要嚴格按照格式書寫,例如:將路徑寫成“C:\STUDENT\ch01_01\ch01_01.c”是不正確的,這一點要特別注意。路徑寫成“C:\\STUDENT\\ch01_01\\ch01_01.c”才是正確的,這里的“\\”的含義是:第一個“\”代表轉義字符,第二個“\”才是字符本身。

讀字符函數——fgetc函數

寫字符函數——fputc函數

10.3文件的讀寫

文件的讀寫操作由文件讀寫函數完成,常用的讀寫函數有fputc、fgetc、fread、fwrite、fputs、fgets、fprintf、fscanf、putw、getw等。

10.3.1字符讀寫函數

fgetc函數用來從指定的文件讀入一個字符,該文件必須是讀或寫方式打開的。fgetc函數的調用格式如下:

ch=fgetc(fp);

其中fp為文件類型指針,ch為字符變量。fgetc函數返回的字符賦給字符變量ch。如果在執行fgetc函數讀字符時遇到文件結束符,則該函數返回一個結束標志EOF(-1)。如果想從磁盤文件順序讀入字符并在屏幕上顯示出來,可以用以下的程序段:

ch=fgetc(fp);

while(ch!=EOF){

putchar(ch);

ch=fgetc(fp);}讀字符函數——fgetc函數

fputc函數用來將一個字符寫入指定的文件中,該函數的調用格式為:

fputc(ch,fp);

其中ch可以是一個字符常量,也可以是一個字符變量。fp是文件指針變量。該函數的作用是將字符(ch的值)輸出到fp所指定的文件中去。fputc函數也帶回一個值,如果輸出成功,則返回值就是輸出的字符,如果輸出失敗,則返回EOF(-1)。寫字符函數——fputc函數#include<stdlib.h>#include<stdio.h>intmain(){FILE*fp;charch,filename[10];

printf("請輸入所用的文件名:");

scanf("%s",filename);

if((fp=fopen(filename,"w"))==NULL)//打開輸出文件并使fp指向此文件

{

printf("無法打開此文件\n");//如果打開時出錯,就輸出"打不開"的信息

exit(0);//終止程序*/}

ch=getchar();//此語句用來接收在執行scanf語句時最后輸入的回車符

printf("請輸入一個準備存儲到磁盤的字符串(以#結束):");

ch=getchar();//接收從鍵盤輸入的第一個字符

while(ch!='#')//當輸入'#'時結束循環

{

fputc(ch,fp);//向磁盤文件輸出一個字符

putchar(ch);//將輸出的字符顯示在屏幕上

ch=getchar();//再接收從鍵盤輸入的一個字符

}

fclose(fp);//關閉文件

putchar(10);//向屏幕輸出一個換行符,換行符的ASCII代碼為10return0;}例10-1例10-2#include<stdio.h>#include<stdlib.h>intmain(){FILE*in,*out;charch,infile[10],outfile[10];//定義兩個字符數組,分別存放兩個文件名

printf("輸入讀入文件的名字:");

scanf("%s",infile);//輸入一個輸入文件的名字

printf("輸入輸出文件的名字:");

scanf("%s",outfile);//輸入一個輸出文件的名字

if((in=fopen(infile,"r"))==NULL)//打開輸入文件

{printf("無法打開此文件\n");exit(0);}

if((out=fopen(outfile,"w"))==NULL)//打開輸出文件

{printf("無法打開此文件\n");exit(0);}

while(!feof(in))//如果未遇到輸入文件的結束標志

{ch=fgetc(in);//從輸入文件讀入一個字符,暫放在變量ch中

fputc(ch,out);//將ch寫到輸出文件中

putchar(ch);//將ch顯示在屏幕上

}putchar(10);//顯示完全部字符后換行

fclose(in);//關閉輸入文件

fclose(out);//關閉輸出文件

return0;}10.3.3字符串讀寫函數

寫字符串函數——fputs

讀字符串函數——fgets

字符串讀寫函數處理的文件類型主要是文本文件,分為讀字符串函數和寫字符串函數。

寫字符串函數——fputs

fputs函數的功能是向指定的文件寫入一個字符串,其調用形式為:

fputs(字符串,文件指針);

字符串可以是字符串常量,也可以是字符數組名或指針變量,例如:

fputs("Human",fp);

上述語句的含義是把字符串“Human”寫入fp所指的文件之中。

讀字符串函數——fgets

fgets函數的功能是從指定的文件中讀一個字符串到字符數組中,其調用形式為:

fgets(str,n,fp);

函數中的參數str是字符數組名;n是一個正整數,表示從文件中讀出的字符串不超過n-1個字符。在向字符數組讀入的最后一個字符后加上字符串結束標志'\0'。如果在讀n-1個字符之前遇到換行符或EOF,讀入工作結束。例如:

fgets(ch,50,fp);

上述語句的含義是從fp所指的文件中讀出49個字符送入字符數組ch中。示例10_3、10_3_210.3.4格式化讀寫函數

文件的格式化讀寫函數和以前學習的格式化輸入/輸出函數很類似,對于格式化輸入/輸出函數,只能和標準輸入/輸出設備文件打交道;而有了格式化的讀寫函數之后,不但可以處理標準設備的輸入/輸出,而且可以處理磁盤文件中的數據。

格式化寫函數fprintf

格式化讀函數fscanf

格式化寫函數fprintf

格式化寫函數fprintf的調用格式為:

fprintf(文件指針,格式字符串,輸出列表);例如:

fprintf(fp,"%d%c",j,ch);

上述語句的作用是將整型變量j和字符型變量ch的值按%d和%c的格式輸出到fp所指的文件上。

格式化讀函數fscanf

格式化讀函數fscanf的調用格式為:

fscanf(文件指針,格式字符串,輸入列表);例如:

fscanf(fp,"%d%s",&i,str);若此時fp所指的文件中存放著以下的數據:

6happynewyear

上述語句的作用是將6賦給整型變量i,將“happynewyear”賦給字符型數組str。

10.3.2數據讀寫函數

寫數據函數——fwrite函數

讀數據函數——fread函數

寫數據函數——fwrite函數

寫數據塊函數調用的一般形式為:

fwrite(buffer,size,n,fp);

其中各個參數的含義及說明如表10.4所示。

參數含義說明

buffer是一個字符型指針,它表示存放輸出數據的變量地址或數組首地址。size是一個無符號整型,表示數據塊的字節數n無符號整型,表示要讀寫的數據塊塊數每個數據是size個字節

fp表示文件指針表10-4fwrite函數中各個參數的含義及說明讀數據函數——fread函數讀數據塊函數調用的一般形式為:

fread(buffer,size,n,fp);

其中的buffer是一個字符型指針,表示存放讀入數據的變量地址或數組首地址。size、n、fp的含義見上表。例如:

fread(a,4,8,fp);

上述語句的含義是從fp所指的文件中,每次讀4個字節,也就是把一個實數送入實數數組a中,連續讀8次,即讀入8個實數并送到數組a中。示例10_4_1、10_4_2、10_4_310.3.5其他讀寫函數

除了上面介紹的讀寫函數外,大部分的C語言編譯系統還提供了對磁盤文件讀寫一個字(整數)的函數——putw和getw。

但putw和getw并不是ANSIC標準定義的函數,所以如果所用的C語言編譯系統不提供這兩個函數,可以按如下的形式自定義這兩個函數。

putw函數的定義

getw函數的定義putw函數的定義putw(inti,FILE*fp){ char*s; s=&i; putc(s[0],fp); puts(s[1],fp); return(i);}getw函數的定義

getw(FILE*fp){ char*s;

inti; s=&i; s[0]=getc(fp); s[1]=getc(fp); return(i);}例如:putw(200,fp);上述語句的功能是將整數200輸出到fp所指向的文件中。10.4文件的定位

前面介紹的對文件的讀寫方式都是順序讀寫,也就是讀寫文件只能從頭開始,順序讀寫各個數據。但在實際問題中常常要求只讀寫文件中某一指定的部分。為了解決這個問題,C語言引入了隨機讀寫的概念。所謂“隨機讀寫”是將文件內部的位置指針移動到需要讀寫的位置后再進行讀寫,這種讀寫稱為隨機讀寫。實現隨機讀寫的關鍵是按要求移動位置指針,這稱為文件的“定位”。移動文件內部位置指針的函數主要有兩個,即rewind函數和fseek函數。10.4.1文件頭定位函數

當讀取了文件中若干個數據后,又要從頭讀取數據,這時就需要將文件內部指針重新指向文件頭,C語言提供的文件頭定位函數rewind就可以將文件指針重新指定到文件頭。該函數的調用格式為:

rewind(文件指針);

其功能是把文件內部的位置指針移到文件開頭,如果定位成功,返回0;否則,返回非0。10.4.2文件隨機定位函數

前面學習的文件讀寫函數主要是用來讀寫順序文件的。例如:如果要讀取文件中的第6個數據,則打開文件后必須先讀取前5個數據后,在讀取1個數據才是所需要的數據。而文件隨機定位函數可以使文件內部位置指針直接指向第6個數據,在讀取當前一個數據就可以。

fseek函數用來移動文件內部位置指針,其調用形式為:

fseek(文件指針,位移量,起始點);

“文件指針”指向被移動的文件。“位移量”表示移動的字節數,要求位移量是long型數據,以便在文件長度大于64KB時不會出錯。當用常量表示位移量時,要求加后綴“L”。

“起始點”表示從何處開始計算位移量,C語言規定的起始點有三種:文件首、當前位置和文件尾,表示方法可以用下表來說明。

起始點表示符號數字表示文件首SEEK_SET0當前位置SEEK_CUR1文件末尾SEEK_END2表10-5起始點的表示方法

例如:

fseek(fp,200L,0);

上述語句的功能是把位置指針移到距文件首200個字節處。

10.4.3流式文件的定位函數

用ftell()函數可以返回文件指針的當前位置。其調用格式為:

ftell(fp);

該函數的返回值為長整型數,表示相對于文件頭的字節數,出錯時返回-1L。例如:

longi;if((i=ftell(fp))==-1L)

printf("Afileerrorhasoccurredat%ld.\n",i);上述程序段可以通知用戶出現了文件錯誤。

示例10_5、10_610.4.4判斷文件結束函數feof

程序從一個磁盤文件中逐個讀取字符并輸出到屏幕上顯示,在while循環中常以EOF作為文件結束標志。這種以EOF作為文件結束標志的文件,必須是文本文件。在文本文件中數據都是以字符的ASCII代碼值的形式存放。我們知道,ASCII代碼值的范圍是0~255,不可能出現-1,因此可以用EOF作為文件結束標志。當把數據以二進制形式存放到文件中時,就

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論