C語言文件的輸入與輸出_第1頁
C語言文件的輸入與輸出_第2頁
C語言文件的輸入與輸出_第3頁
C語言文件的輸入與輸出_第4頁
C語言文件的輸入與輸出_第5頁
已閱讀5頁,還剩43頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第11章文件的輸入與輸出C語言程序設(shè)計(jì)1

本章介紹文件概念及其相關(guān)術(shù)語、C語言輸入輸出的實(shí)現(xiàn)方法、流的概念和流式文件的輸入和輸出、文本文件的輸入輸出和二進(jìn)制文件的輸入輸出、文件的順序輸入輸出和文件的隨機(jī)輸入輸出。

對輸入輸出的低層接口、文件在數(shù)據(jù)庫和漢字顯示方面的應(yīng)用、流式文件庫函數(shù)的設(shè)計(jì)也做了相應(yīng)的介紹。

內(nèi)容摘要2重點(diǎn)講解11.1

文件概述

11.2

FILE指針和標(biāo)準(zhǔn)流式文件

11.3

流式文件的順序輸入輸出11.4

流式文件的隨機(jī)輸入輸出11.5

其它文件操作函數(shù)11.6

輸入輸出的低層接口11.7

流式文件系統(tǒng)中庫函數(shù)的設(shè)計(jì)小結(jié)3

本章討論關(guān)于計(jì)算機(jī)的存儲器與I/O設(shè)備之間數(shù)據(jù)交換的程序設(shè)計(jì)問題。目錄問題背景計(jì)算機(jī)組成原理圖

運(yùn)算器存儲器控制器輸入設(shè)備輸出設(shè)備數(shù)據(jù)線地址線控制線計(jì)算機(jī)“內(nèi)部”√√√√I/O設(shè)備外部存儲器顯示器打印機(jī)鍵盤…硬盤軟盤光盤U盤…(I/O)(O)(O)(

I

)(I/O)(I/O)(I或I/O)標(biāo)準(zhǔn)輸入設(shè)備標(biāo)準(zhǔn)輸出設(shè)備4

基于操作系統(tǒng)的軟件系統(tǒng)是將一組應(yīng)用相關(guān)的數(shù)據(jù)構(gòu)成一個邏輯單位,存儲在外部存儲器之中的。這個邏輯單位被稱為文件,以文件名加以標(biāo)識。目錄11.1文件概述

文件是指內(nèi)存以外介質(zhì)上以某種形式組織起來的數(shù)據(jù)集合。在C語言中,文件中的數(shù)據(jù)分為兩種數(shù)據(jù)格式存儲。

文件目錄區(qū)文件數(shù)據(jù)區(qū)外部存儲器存儲空間組織示意圖F1.TXTHello!…文件頭文件尾文本格式文件二進(jìn)制格式文件5

第一類文本格式:將文件數(shù)據(jù)區(qū)的每個字節(jié)解釋為一個字符,回車符‘\n’解釋為行結(jié)束標(biāo)志(回車符之間的符號串稱為一行)。文本文件數(shù)據(jù)區(qū)存儲示意圖main

(

){

\nprin

tf

(“h

i”)

;

\n}

\n

EOFmain(){

printf(“hi”);}

_

這種格式文件稱為文本文件、行文文件、正文文件或純文本文件。

文本文件是以字符序列形式存儲數(shù)據(jù)的文件。6

如果將內(nèi)存數(shù)據(jù)按文本文件存儲到外存中,則

C

語言通常需要將內(nèi)存數(shù)據(jù)按指定格式轉(zhuǎn)換成字符形式。例如,intx=128;

轉(zhuǎn)換格式:“%d”0000

0000

1000

0000

x內(nèi)存:0011

0001

0011

0010

0111

0000

外存:‘1’‘2’‘8’

如果將存儲在外存中的文本文件數(shù)據(jù)取回到內(nèi)存,則C語言通常需要將按指定格式轉(zhuǎn)換成內(nèi)存數(shù)據(jù)形式。例如,intx=128;

轉(zhuǎn)換格式:“%d”0000

0000

1000

0000

x內(nèi)存:0011

0001

0011

0010

0111

0000

外存:‘1’‘2’‘8’寫文件讀文件7

如果當(dāng)將內(nèi)存多個數(shù)據(jù)寫入文本文件的時候,特別注意的是:在兩個數(shù)據(jù)之間增加必的間隔符。目的在于讀文本文件時,能夠保證獲得數(shù)據(jù)轉(zhuǎn)換的正確性。例如,intx=128,y=821,a,b;轉(zhuǎn)換格式:“%d%d”或“%d%d”0000

0000

1000

0000

x0000

0011

0011

0101

y內(nèi)存:‘1’‘2’‘8’‘1’‘2’‘8’外存:內(nèi)存:-

a-

b128821×y內(nèi)存:0000

0000

1000

0000

0000

0011

0011

0101

內(nèi)存:外存:0000

0000

1000

0000ab‘1’‘2’‘8’‘8’‘2’‘1’‘

’0000

0011

0011

0101

x8

C語言是將鍵盤、顯示器和打印機(jī)設(shè)備視同為文本文件進(jìn)行處理的。對于輸出設(shè)備顯示器和打印機(jī),遇到輸出回車符時,便換行顯示或打印。鍵盤輸入緩沖數(shù)據(jù)區(qū)存儲示意圖main

(

){

\nprin

tf

(“h

i”)

;

\n}

\n

EOF打印機(jī)輸出緩沖數(shù)據(jù)區(qū)存儲示意圖main

(

){

\nprin

tf

(“h

i”)

;

\n}

\n

EOF顯示器輸出緩沖數(shù)據(jù)區(qū)存儲示意圖main

(

){

\nprin

tf

(“h

i”)

;

\n}

\n

EOF在字符模式下,顯示器和打印機(jī)邏輯上呈現(xiàn)文本特性。9

第二類二進(jìn)制格式:文件數(shù)據(jù)區(qū)僅按每個二進(jìn)制位解釋為0或1。這種格式的文件稱為二進(jìn)制文件。二進(jìn)制文件是以二進(jìn)制數(shù)字0/1序列形式存儲數(shù)據(jù)的文件。二進(jìn)制文件存儲示意圖0000

0000

1000

0000

0000

0000

1000

0000

如果將內(nèi)存數(shù)據(jù)按二進(jìn)制文件存儲在外存中,則

C

語言不需要轉(zhuǎn)換,直接按內(nèi)存數(shù)據(jù)0/1形式存儲。例如,intx=128;輸出格式:二進(jìn)制位0000

0000

1000

0000

x內(nèi)存:外存:write0000

0000

1000

0000

如果將存儲在外存中二進(jìn)制文件的數(shù)據(jù)取回內(nèi)存,則C語言不需要轉(zhuǎn)換,直接取回即可,其數(shù)值按內(nèi)存單元之?dāng)?shù)據(jù)類型解釋。例如,intx=128;輸出格式:二進(jìn)制位0000

0000

1000

0000

x內(nèi)存:外存:read0000

0000

1000

0000

10

C語言對文件的讀寫提供有兩種方式:順序讀寫和隨機(jī)讀寫。

無論那種讀寫方式,文件采用一個文件讀寫指針記錄對于文件的當(dāng)前讀寫位置,并在一次讀寫后自動向文件尾方向移動。

00110001

00110010

01100001……‘1’‘2’‘a(chǎn)’讀前讀后

按文本格式“%c”轉(zhuǎn)換讀入1個char數(shù)據(jù):00110001。

00110001

00110010

01100001……‘1’‘2’‘a(chǎn)’讀前讀后

按文本格式“%d”轉(zhuǎn)換讀入1個int數(shù)據(jù):00000000

00001100。12

其移動距離取決于轉(zhuǎn)換格式之對應(yīng)字符串的長度。11

00110001

00110010

01100001……‘1’‘2’‘a(chǎn)’讀前讀后

按二進(jìn)制格式讀入1個char數(shù)據(jù):00110001。

00110001

00110010

01100001……‘1’‘2’‘a(chǎn)’讀前讀后

按二進(jìn)制讀入1個int數(shù)據(jù):00110001

00110010。

C語言對文件的讀寫提供有兩種方式:順序讀寫和隨機(jī)讀寫。

無論那種讀寫方式,文件采用一個文件讀寫指針記錄對于文件的當(dāng)前讀寫位置,并在一次讀寫后自動向文件尾方向移動。12594

其移動距離取決于內(nèi)存單元之?dāng)?shù)據(jù)類型的長度。12

順序讀寫方式:打開文件時文件讀寫指針指向文件頭或文件尾,讀寫一個

“數(shù)據(jù)”

后,讀寫指針自動指向下一個

“數(shù)據(jù)”

或文件尾。程序無法修改文件讀寫指針,文件指針始終往文件尾方向移動。

data1data2data3data4datan-1

datan………順序讀文件過程示意數(shù)據(jù)的劃分取決于讀寫方式和轉(zhuǎn)換格式!

隨機(jī)讀寫方式:以二進(jìn)制格式打開文件時,文件讀寫指針指向文件頭或文件尾,讀寫一個“數(shù)據(jù)”后讀寫指針自動指向下一個“數(shù)據(jù)”或文件尾。程序可以修改文件讀寫指針,文件指針可在頭尾兩個方向往返移動。

data1data2data3data4datan-1

datan………隨機(jī)讀文件過程示意13標(biāo)準(zhǔn)I/O函數(shù)是基于I/O流的操作。流是從源點(diǎn)到終點(diǎn)方向流動的數(shù)據(jù)。文件是“存儲”在I/O設(shè)備上的數(shù)據(jù)的抽象;流是內(nèi)存與I/O設(shè)備之間流動的數(shù)據(jù)的抽象。實(shí)現(xiàn)時,流存儲在I/O緩沖區(qū)中。實(shí)現(xiàn)C語言應(yīng)用程序的I/O運(yùn)算之兩種方法:內(nèi)存I/O設(shè)備I/O緩沖區(qū)文件流輸入流輸入流C語言標(biāo)準(zhǔn)I/O函數(shù)實(shí)現(xiàn)模型

標(biāo)準(zhǔn)I/O函數(shù)是基于I/O流的操作。C語言實(shí)現(xiàn)“字符流和BIT流特性差異的I/O設(shè)備”之間的轉(zhuǎn)換,即各種I/O設(shè)備的差異對于應(yīng)用程序是透明的?;贗/O流操作的文件稱為流式文件。調(diào)用

C提供的I/O函數(shù)--標(biāo)準(zhǔn)I/O函數(shù)調(diào)用OS提供的I/O函數(shù)--底層I/O函數(shù)

底層I/O函數(shù)是非緩沖的非基于I/O流的操作,基于非I/O流操作的文件稱為非流式文件。

在非流式文件中,通過由操作系統(tǒng)分配提供的文件描述符(描述字或句柄)進(jìn)行I/O操作。

無論是緩沖或者非緩沖的文件,其I/O操作的步驟如下,打開文件時,確定了文件讀寫格式和讀寫方式!

⑴打開文件——建立文件指針或文件描述符與文件間聯(lián)系;⑵對文件進(jìn)行讀寫操作;⑶關(guān)閉文件——取消文件指針或文件描述符與文件間聯(lián)系。

1411.2

FILE指針和標(biāo)準(zhǔn)流式文件

目錄

FILE是C語言標(biāo)準(zhǔn)中定義的一種結(jié)構(gòu)類型名稱。FILE類型的結(jié)構(gòu)變量記載關(guān)于流的控制方面的全部信息。

不同的C編譯器關(guān)于FILE結(jié)構(gòu)類型的定義會略有差異,但提供的庫函數(shù)原型都是滿足C語言標(biāo)準(zhǔn)。typedef

struct{

shortlevel;/*緩沖區(qū)空滿*/

unsignedflags;/*文件狀態(tài)標(biāo)志*/

char

fd;/*文件描述符*/

unsignedcharhold;

/*非緩沖回送字符*/

short

bsize;

/*緩沖區(qū)大小*/

unsignedchar*buffer;/*指向緩沖區(qū)指針*/

unsignedchar*

curp;/*當(dāng)前讀寫位置指針*/

unsigned

istemp;/*臨時文件描述符*/

shorttoken;/*有效性檢驗(yàn)標(biāo)志*/}FILE;

/*結(jié)構(gòu)類型命名*/15

_streams[]是在頭文件stdio.h中定義的、由系統(tǒng)創(chuàng)建、賦值和更新FILE類型的數(shù)組變量,其數(shù)組元素個數(shù)是由系統(tǒng)宏定義的、可同時打開的文件數(shù)目。#defineOPEN_MAX20

externFILE_Cdecl

_streams[];_streams[]FILE*fp;FILEFILE…FILE…FILE

程序中僅使用FILE*型變量,通常簡稱為FILE指針。01…K…OPEN_MAX-1fp=fopen(…,…);/*fopen()打開文件函數(shù)*/fpFILE*fclose(fp);/*fclose()關(guān)閉文件函數(shù)*/文件IO操作步驟16_streams[]FILEFILEFILEFILEFILE…01234…#definestdin(&_streams[0])/*標(biāo)準(zhǔn)輸入設(shè)備,通常是鍵盤*/#definestdout(&_streams[1])/*標(biāo)準(zhǔn)輸出設(shè)備,通常是顯示器

*/#definestderr(&_streams[2])/*標(biāo)準(zhǔn)出錯設(shè)備--顯示器

*/#definestdaux(&_streams[3])/*標(biāo)準(zhǔn)輔助設(shè)備

*/#definestdprn(&_streams[4])/*標(biāo)準(zhǔn)打印設(shè)備

*/

TurboC中已經(jīng)定義了多個系統(tǒng)的標(biāo)準(zhǔn)流式文件,其聲明如下。getchar、gets和scanf函數(shù)是從stdin文件讀數(shù)據(jù);putchar、puts和printf函數(shù)則是向stdout

文件寫數(shù)據(jù)。stdinstdoutstderrstdauxstdprn…

C標(biāo)準(zhǔn)規(guī)定,標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)出錯三個標(biāo)準(zhǔn)文件(文本流),在C程序開始運(yùn)行時,由系統(tǒng)自動打開。1711.3流式文件的順序輸入輸出

目錄

文件打開函數(shù)

fopen()

聲明如下,功能是按照參數(shù)

mode

指定方式,打開參數(shù)

filename

指定文件,返回

filename

的文件指針。如果失敗返回NULL。FILE*_Cdecl

fopen(constchar*filename,constchar*mode);文件IO操作步驟

例如,按文本格式、順序?qū)懛绞酱蜷_文件c:\test.dat。

FILE

*

fp;

fp=fopen(“c:\test.dat”,”w”);fp_streams[

]disk……test.dat11.3.1

文件的打開與關(guān)閉18

可以選擇的文件打開方式mode如下。其中,r表示只讀,w表示只寫,a表示添加,+表示更新,b表示二進(jìn)制文件。

如果文件打開方式中不含有

“b”

,則表示以文本格式打開。創(chuàng)建文件時,如果創(chuàng)建文件已經(jīng)存在,則內(nèi)容被清空。

r 以只讀方式文本格式打開w 以只寫方式文本格式打開或創(chuàng)建a 以尾部添加只寫方式文本格式打開或創(chuàng)建rb

以只讀方式二進(jìn)制格式打開wb

以只寫方式二進(jìn)制格式打開或創(chuàng)建ab

以尾部添加只寫方式二進(jìn)制格式打開或創(chuàng)建r+ 以更新(讀寫)方式文本格式打開w+ 以更新(讀寫)方式文本格式打開或創(chuàng)建a+ 以尾部添加、更新方式文本格式打開或創(chuàng)建r+b

或rb+ 以更新(讀寫)方式二進(jìn)制格式打開w+b

或wb+ 以更新(讀寫)方式二進(jìn)制格式打開或創(chuàng)建a+b

或ab+ 以尾部添加、更新方式文本格式打開或創(chuàng)建19

文件關(guān)閉函數(shù)fclose()聲明如下,功能是關(guān)閉stream文件指針

“指向”的文件,返回值0表示正確執(zhí)行,EOF表示出錯。int_Cdecl

fclose(FILE*stream);文件IO操作步驟

例如,按文本格式、順序?qū)懛绞酱蜷_文件c:\test.dat,之后關(guān)閉該文件。

FILE

*

fp;

fp=fopen(“c:\test.dat”,”w”);

fclose(fp);fp_streams[

]disk……test.dat20例11.3

文件打開、關(guān)閉、以及讀寫操作舉例。文件以文本文件格式創(chuàng)建,以二進(jìn)制文件的形式讀取,目的是觀察文本文件在磁盤中的存儲方式。

#include"stdio.h"voidmain(void){chara[20];unsignedcharu,i=0;

FILE*fin,*fout;

fout=fopen("c:\\abc.dat","w+");

while(gets(a)!=NULL)fprintf(fout,"%s",a);fclose(fout);

fin=fopen("c:\\abc.dat","r+b");

while(!feof(fin)){

fread(&u,sizeof(unsignedchar),1,fin);

if(!feof(fin)){printf("%04X%04X\t",i++,u);if(i%4==0)printf("\n");}}

printf("\n");

fclose(fin);}文件IO操作步驟2111.3.2

文件的重定向

文件的重定向函數(shù)freopen()聲明如下,功能是在關(guān)閉fp指向的文件之后,fp重指向按照mode方式打開的、filename指定的文件,函數(shù)返回新打開的文件指針。如果失敗返回NULL。FILE*_Cdecl

refopen(constchar*filename,constchar*mode,FILE*fp);fp_streamsdisk……oldfilenewfile

例如,按文本格式、順序?qū)懛绞酱蜷_文件c:\test.dat。

FILE

*

fp;

fp=fopen(“c:\oldfile”,”r”);

refopen(“c:\newfile”,”w”,fp);22voidmain(int

argc,char*argv[]){

int

ch;

if(argc!=3){printf("Argumentserror!\n");exit(-1);}if(freopen(argv[1],"r",stdin)==NULL){

/*stdin指向source_file*/

printf("Can'topen%sfile!\n",argv[1]);exit(-1);}

freopen(argv[2],"w",stdout);/*stdout指向target_file*/

while((ch=getchar())!=EOF)/*從source_file中讀字符*/

putchar(ch);/*向target_file中寫字符,實(shí)現(xiàn)拷貝復(fù)制*/

fclose(stdin);/*關(guān)閉source_file*/

fclose(stdout);/*關(guān)閉target_file*/}例11.4利用輸入輸出重定向?qū)崿F(xiàn)OS命令行格式如下的文本文件的拷貝復(fù)制。copysource_file

target_file其中,copy是可執(zhí)行文件名,source_file是源文件名,target_file是目標(biāo)文件名。

提示:包括標(biāo)準(zhǔn)文件在內(nèi)的任意打開的文件都可以重定向。2311.3.3

基于字符的文件讀/寫

int

fgetc(FILE*stream);int

fputc(intc,FILE*stream);int

fgetchar(void);int

fputchar(intc);int

_fgetc(FILE*stream);/*僅供宏getc()使用*/int

_fputc(charc,FILE*stream);/*僅供宏putc()使用*/int

ungetc(intc,FILE*stream);

C

提供的基于字符的IO函數(shù)原型如下,其聲明在stdio.h

中。即使用時,必須先用#include<stdio.h>或#include"stdio.h"。

這些標(biāo)準(zhǔn)IO函數(shù)是對標(biāo)準(zhǔn)文件或以文本格式打開的文件進(jìn)行操作的!24int

fgetc(FILE*stream)函數(shù)

從文件指針

stream

指向的文件中讀取一個字符,并將該字符作為unsignedchar類型轉(zhuǎn)換為整型值返回。遇到文件尾或讀操作出錯時返回EOF。#include“stdio.h”#include“stdlib.h”voidmain(void){FILE*fp;charc;

fp=fopen(“C:\test.dat”,“r”);

while((ch=fgetc(fp))!=EOF)

printf(“%c”,ch);

fclose(fp);}

例如,設(shè)計(jì)一個程序?qū)⒂脖P根目錄下的文本文件

“C:\test.dat”

的內(nèi)容顯示在屏幕上。int

fputc(intc,FILE*stream)函數(shù)

將參數(shù)c轉(zhuǎn)換成為unsignedchar類型寫到文件指針stream指向的輸出流的當(dāng)前位置處,返回值是被寫字符。如果寫操作出錯或遇到文件尾函數(shù)返回EOF。int

fgetchar(void)函數(shù)

從標(biāo)準(zhǔn)輸入文件stdin中讀入字符。

int

fgetchar(void){return

fgetc(stdin);}

將參數(shù)c轉(zhuǎn)換成為unsignedchar類型寫到標(biāo)準(zhǔn)文件stdout。

int

fputchar(void){return

fputc(stdout);}

int

fputchar(intc)函數(shù)

25int

_fgetc(FILE*stream)函數(shù)、

int

_fputc(FILE*stream)函數(shù)

函數(shù)_fgetc和_fputc通常是供宏定義中使用的。#definegetchar()

getc(stdin)#defineputchar(c)

putc((c),stdout)#definegetc(f)((--((f)->level)>=0)?(unsignedchar)(++(f)->curp)[-1]:_fgetc(f))#defineputc(c,f)((++((f)->level)<0)?(unsignedchar)((++(f)->curp)[-1]=(c)):_fputc((c),f))int

ungetc(intc,FILE*stream)函數(shù)

將參數(shù)c之低字節(jié)作為字符回送stream流中并作為函數(shù)值返回。如果失敗返回EOF。_streams……c

Ch

Clstream……abccl2611.3.4

基于字符串的文件讀/寫

C

提供的基于字符串的IO函數(shù)原型如下,其聲明在stdio.h之中。即使用時,必須先用#include<stdio.h>或#include"stdio.h"。

char*gets(char*s);int

puts(constchar*s);char*fgets(char*s,intn,FILE*stream);int

fputs(constchar*s,FILE*stream);這些標(biāo)準(zhǔn)IO函數(shù)是對標(biāo)準(zhǔn)文件或以文本格式打開的文件進(jìn)行操作的!

調(diào)用標(biāo)準(zhǔn)C提供的字符串輸入輸出函數(shù)每次從輸入文件中讀或者向輸出文件寫一個字符串。27char*gets(char*s)函數(shù)

從標(biāo)準(zhǔn)輸入流stdin中讀一行字符,存入字符指針

s

指向的內(nèi)存單元,行尾部的換行符‘\n’被替換成‘\0’,返回值是指向輸入字符串的指針s。如果遇到文件尾或出錯,返回NULL。char*puts(constchar*s)函數(shù)

將指針

s

指向的字符串寫入標(biāo)準(zhǔn)輸出流stdout,并在行尾添加換行符‘\n’,函數(shù)返回一個非負(fù)值。如果出錯返回EOF。char*fgets(char*s,intn,FILE*stream)函數(shù)

從stream指向的流中讀一行(輸入行長度<n時),或至多讀n-1個字符(行長度n時),存入到s指向的內(nèi)存單元,返回輸入字符串的指針s。如果出錯或遇文件尾返回NULL。char*fputs(constchar*s,FILE*stream)函數(shù)

將指針s指向的字符串寫入stream指向的流中,函數(shù)返回一個非負(fù)值。如果出錯返回EOF。2811.3.5

文件的格式讀/寫

C

提供的格式讀寫的IO函數(shù)原型如下,其聲明在stdio.h中。即使用時,必須先用#include<stdio.h>或#include"stdio.h"。

int

printf(constchar*format,...);int

scanf(constchar*format,...);int

fprintf(FILE*stream,constchar*format,...);int

fscanf(FILE*stream,constchar*format,...);int

sprintf(char*buffer,constchar*format,...);int

sscanf(constchar*buffer,constchar*format,...);

這些標(biāo)準(zhǔn)IO函數(shù)是對標(biāo)準(zhǔn)文件或以文本格式打開的文件進(jìn)行操作的!后面4個函數(shù)功能和使用方法,與第3章的printf函數(shù)和scanf函數(shù)相同或類似,差異在于輸入輸出文件不同。

輸出函數(shù)正常時都返回輸出字符個數(shù),寫操作出錯時返回負(fù)值。輸入函數(shù)時都返回已輸入項(xiàng)數(shù),如果讀操作出錯都返回EOF。

2911.3.6

文件的直接讀/寫

C

提供的直接讀寫的IO函數(shù)原型如下,其聲明在stdio.h中。即使用時,必須先用#include<stdio.h>或#include"stdio.h"。

size_t

fread(void*ptr,size_tsize,size_tn,FILE*stream);size_t

fwrite(constvoid*ptr,size_tsize,size_t

n,FILE*stream);這些標(biāo)準(zhǔn)IO函數(shù)是對標(biāo)準(zhǔn)文件或以文本格式打開的文件進(jìn)行操作的!

文件直接輸入輸出,又稱為文件成組輸入輸出。它指通過一次I/O能夠完成若干條記錄(record)的輸入或輸出。記錄是一個十分寬泛的概念。通常,記錄是指由若干個字段組成的數(shù)據(jù)集。在

C

語言中可以采用結(jié)構(gòu)數(shù)據(jù)類型表示,結(jié)構(gòu)的成員對應(yīng)于記錄的字段。

fread和fwrite函數(shù)也適用于二進(jìn)制形式文件的讀寫。30size_t

fread(void*ptr,size_tsize,size_tn,FILE*stream)函數(shù)

從stream指向的輸入文件中讀取至多n個大小為size的記錄,存入到指針ptr指向的內(nèi)存單元中,返回值是實(shí)際讀取記錄數(shù)。size_t

fwrite(constvoid*ptr,size_tsize,size_t

n,FILE*stream)函數(shù)

從指針ptr指向的內(nèi)存緩沖區(qū)中取n個大小為size的記錄,寫到指針stream指向的輸出文件中,返回值是寫出的記錄數(shù)。當(dāng)返回值小于n時,表示寫操作出錯。

文件尾測試函數(shù)feof(),如遇到文件尾,返回非0值,否則返回0。出錯測試函數(shù)ferror(),如果出錯,返回非0值,否則返回0。

重要提示:實(shí)際上,不論文件是按文本格式,還是二進(jìn)制格式打開,函數(shù)fread和fwrite的讀寫都是指定的字節(jié)數(shù)(=size×n),直接進(jìn)行讀寫操作的,不做任何轉(zhuǎn)換。即函數(shù)fread和fwrite的讀寫是二進(jìn)制位流。31#include"stdio.h"voidmain(void){chari=0x41,j=0x42,a,b;FILE*fp;

fp=fopen("d:\\test.txt","w");fwrite(&i,sizeof(char),1,fp);fwrite(&j,sizeof(char),1,fp);

fclose(fp);

printf("%c%c\n",a,b);

fp=fopen("d:\\test.txt","r");fread(&a,sizeof(char),1,fp);fread(&b,sizeof(char),1,fp);

fclose(fp);

printf("%c%c\n",a,b);}

例如,下面程序給出了函數(shù)fwrite和fread基本用法和WEN文件IO操作效果。(‘A’的ACSII碼:0x41)10000010i01000010j--------a--------bfptest.txt10000010010000101000001001000010◎¥AB3211.4

流式文件的隨機(jī)輸入輸出11.4.1

文件定位函數(shù)

目錄

C

提供的文件定位函數(shù)原型如下,其聲明在stdio.h中。即使用時,必須先用#include<stdio.h>或#include"stdio.h"。

流式文件的隨機(jī)輸入輸出是指對文件的讀寫可以從文件內(nèi)指定的位置進(jìn)行,而不必每次從頭順序開始。int

fseek(FILE*stream,longoffset,intorigin);longftell(FILE*stream);int

fgetpos(FILE*stream,fpos_t*pos);int

fsetpos(FILE*stream,constfpos_t*pos);voidrewind(FILE*stream);

對二進(jìn)制格式文件和文本格式文件,均可使用定位函數(shù)。33int

fseek(FILE*stream,longoffset,intorigin)函數(shù)

將stream指向的文件之當(dāng)前讀寫指針,定位到origin+offset。如果正常定位,fseek函數(shù)返回0,否則返回非0值。

origin和offset分別稱為基準(zhǔn)點(diǎn)和偏移量。

originoffset

基準(zhǔn)點(diǎn)有三種取值:SEEK_SET、SEEK_CUR和SEEK_END。

#defineSEEK_SET0文件起始位置為基準(zhǔn)點(diǎn)

#defineSEEK_CUR1文件當(dāng)前位置為基準(zhǔn)點(diǎn)

#defineSEEK_END2文件尾部位置為基準(zhǔn)點(diǎn)

C

標(biāo)準(zhǔn):對二進(jìn)制格式文件,基準(zhǔn)點(diǎn)的取值與偏移量無關(guān);對文本格式文件基準(zhǔn)點(diǎn)只能取

0

,而偏移量可以取

0

或ftell函數(shù)的返回值。34longftell(FILE*stream)函數(shù)

讀取文件讀寫指針的當(dāng)前值返回,出錯時返回-1L。int

fgetpos(FILE*stream,fpos_t*pos)函數(shù)

將stream指向文件的讀寫指針當(dāng)前值,保存到pos指針?biāo)傅膄pos_t類型的對象中。成功保存,函數(shù)返回0,否則返回非0值。int

fsetpos(FILE*stream,constfpos_t*pos)函數(shù)

用fgetpos函數(shù)獲得的pos指針?biāo)笇ο笾械闹?,設(shè)置stream所指向文件的當(dāng)前位置。設(shè)置成功函數(shù)返回0,否則返回非0值。

voidrewind(FILE*stream)函數(shù)

將文件指針

stream指向文件的讀寫指針,重新定位到文件的起始位置,清除文件結(jié)束標(biāo)志和出錯標(biāo)志。fp.........文件test.dat之?dāng)?shù)據(jù)區(qū)3511.4.2

文件隨機(jī)讀/寫

利用各種文件的定位函數(shù)和文件的讀寫函數(shù),可以實(shí)現(xiàn)任何文件的隨機(jī)讀寫。

通常,將大量數(shù)據(jù)儲存在文件中,應(yīng)該首先設(shè)計(jì)數(shù)據(jù)存儲格式。之后,按照設(shè)計(jì)的數(shù)據(jù)存儲格式,設(shè)計(jì)應(yīng)用程序,確保對文件進(jìn)行正確的文件指針定位和讀寫操作。換言之,數(shù)據(jù)是什么規(guī)律寫入文件的,通常應(yīng)該按此規(guī)律定位和讀出存儲在文件之中的數(shù)據(jù)。

定位函數(shù)中參數(shù)值,依賴于具體的編譯程序之約定。在軟件開發(fā)時,需要認(rèn)真閱讀所使用的開發(fā)工具的相關(guān)技術(shù)資料!3611.5

其它文件操作函數(shù)11.5.1

文件訪問類函數(shù)

目錄

C標(biāo)準(zhǔn)規(guī)定了五個文件訪問類操作函數(shù)如下。其中,前2個函數(shù)已經(jīng)討論過,剩余3個函數(shù)都是關(guān)于緩沖區(qū)的操作。FILE*_Cdecl

fopen(constchar*filename,constchar*mode);int_Cdecl

fclose(FILE*stream);int

fflush(FILE*stream);int

setvbuf(FILE*stream,char*buf,intmode,size_tsize);voidsetbuf(FILE*stream,char*buf);標(biāo)準(zhǔn)C為規(guī)定了三種緩沖模式:

_IOFBF(全緩沖)

_IOLBF(行緩沖)_IONBF(無緩沖)37int

setvbuf(FILE*stream,char*buf,intmode,size_tsize)函數(shù)

在打開文件之后,其他任何有關(guān)文件的操作執(zhí)行之前,setvbuf函數(shù)被調(diào)用:setvbuf函數(shù)用buf指向的存儲區(qū),作為stream指向流的緩沖,緩沖方式由參數(shù)mode決定,緩沖大小由參數(shù)size決定。調(diào)用成功函數(shù)返回0,否則返回非0值。voidsetbuf(FILE*stream,char*buf)函數(shù)

功能上與setvbuf函數(shù)一樣。不同的是該函數(shù)采用_IOFBF全緩沖,緩沖大小用BUFSIZ,函數(shù)沒有返回值。緩沖大小值BUFSIZ,在stdio.h定義,一般為512個字節(jié)。

將stream指向的輸出緩沖區(qū)或更新緩沖區(qū)(用追加方式打開)中尚未存盤的數(shù)據(jù)強(qiáng)制性的全部寫到介質(zhì)文件中。如果stream為NULL,執(zhí)行fflush操作將使所有緩沖區(qū)的數(shù)據(jù)存盤。寫操作成功函數(shù)返回0,否則置出錯標(biāo)志并返回EOF。int

fflush(FILE*stream)函數(shù)

3811.5.2

文件操作類函數(shù)

C標(biāo)準(zhǔn)規(guī)定了四個文件操作類函數(shù),在stdio.h頭文件中聲明的函數(shù)原型如下。int

remove(constchar*filename);int

rename(constchar*oldname,constchar*newname);FILE*tmpfile(void);char*tmpnam(char*s);實(shí)際上,remove函數(shù)就是DOS的del操作之功能。int

remove(constchar

*filename)函數(shù)

文件刪除函數(shù):刪除以參數(shù)filename指向的字符串為文件名的文件。如果操作成功,remove函數(shù)返回0,否則返回非0值。如果參數(shù)filename指向的文件已經(jīng)打開,remove操作之處理方式由C編譯器自行決定。39int

rename(constchar*

oldname,constchar*newname)函數(shù)

文件換名函數(shù):以參數(shù)

oldname

指向的字符串為舊文件名,更換成以參數(shù)newname指向的字符串為新文件名。如果操作成功,函數(shù)返回0,否則返回非0值。

實(shí)際上,rename函數(shù)就是DOS的ren操作之功能。FILE*tmpfile(void)函數(shù)

以“wb+”方式創(chuàng)建一個臨時二進(jìn)制文件,該臨時文件在文件關(guān)閉或程序結(jié)束時被自動清除。如果調(diào)用成功,函數(shù)返回一個指向創(chuàng)建的臨時文件之文件指針,否則返回NULL。char*

tmpnam(char*s)函數(shù)

產(chǎn)生一個在操作系統(tǒng)的文件系統(tǒng)之下、與已存在的文件不相同的文件名,存入?yún)?shù)s指針指向的字符數(shù)組。如果操作成功,返回參數(shù)s的值,否則返回NULL。4011.5.3

出錯檢測類函數(shù)

C標(biāo)準(zhǔn)規(guī)定了四個文件檢錯類函數(shù),在stdio.h頭文件中聲明的函數(shù)原型如下。voidclearerr(FILE*stream);int

feof(FILE*stream);int

ferror(FILE*stream);voidperror(constchar*s);typedef

struct{

shortlevel;/*緩沖區(qū)空滿*/

unsigned

flags;/*文件狀態(tài)標(biāo)志*/

char

fd;/*文件描述符*/

unsignedcharhold;/*非緩沖回送字符*/

short

bsize;/*緩沖區(qū)大小*/

unsignedchar*buffer;/*指向緩沖區(qū)指針*/

unsignedchar*

curp;/*當(dāng)前讀寫位置指針*/

unsigned

istemp;/*臨時文件描述符*/

shorttoken;/*有效性檢驗(yàn)標(biāo)志*/}FILE;

/*結(jié)構(gòu)類型命名*/41void

clearerr(FILE

*stream)函數(shù)

清除stream所指流的EOF標(biāo)志和出錯標(biāo)志,函數(shù)無返回

溫馨提示

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

評論

0/150

提交評論