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

下載本文檔

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

文檔簡(jiǎn)介

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

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

對(duì)輸入輸出的低層接口、文件在數(shù)據(jù)庫(kù)和漢字顯示方面的應(yīng)用、流式文件庫(kù)函數(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)中庫(kù)函數(shù)的設(shè)計(jì)小結(jié)3

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

運(yùn)算器存儲(chǔ)器控制器輸入設(shè)備輸出設(shè)備數(shù)據(jù)線地址線控制線計(jì)算機(jī)“內(nèi)部”√√√√I/O設(shè)備外部存儲(chǔ)器顯示器打印機(jī)鍵盤(pán)…硬盤(pán)軟盤(pán)光盤(pán)U盤(pán)…(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)成一個(gè)邏輯單位,存儲(chǔ)在外部存儲(chǔ)器之中的。這個(gè)邏輯單位被稱為文件,以文件名加以標(biāo)識(shí)。目錄11.1文件概述

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

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

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

(

){

\nprin

tf

(“h

i”)

;

\n}

\n

EOFmain(){

printf(“hi”);}

_

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

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

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

C

語(yǔ)言通常需要將內(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’

如果將存儲(chǔ)在外存中的文本文件數(shù)據(jù)取回到內(nèi)存,則C語(yǔ)言通常需要將按指定格式轉(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’寫(xiě)文件讀文件7

如果當(dāng)將內(nèi)存多個(gè)數(shù)據(jù)寫(xiě)入文本文件的時(shí)候,特別注意的是:在兩個(gè)數(shù)據(jù)之間增加必的間隔符。目的在于讀文本文件時(shí),能夠保證獲得數(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語(yǔ)言是將鍵盤(pán)、顯示器和打印機(jī)設(shè)備視同為文本文件進(jìn)行處理的。對(duì)于輸出設(shè)備顯示器和打印機(jī),遇到輸出回車(chē)符時(shí),便換行顯示或打印。鍵盤(pán)輸入緩沖數(shù)據(jù)區(qū)存儲(chǔ)示意圖main

(

){

\nprin

tf

(“h

i”)

;

\n}

\n

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

(

){

\nprin

tf

(“h

i”)

;

\n}

\n

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

(

){

\nprin

tf

(“h

i”)

;

\n}

\n

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

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

0000

1000

0000

0000

0000

1000

0000

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

C

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

0000

1000

0000

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

0000

1000

0000

如果將存儲(chǔ)在外存中二進(jìn)制文件的數(shù)據(jù)取回內(nèi)存,則C語(yǔ)言不需要轉(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語(yǔ)言對(duì)文件的讀寫(xiě)提供有兩種方式:順序讀寫(xiě)和隨機(jī)讀寫(xiě)。

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

00110001

00110010

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

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

00110001

00110010

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

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

00001100。12

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

00110001

00110010

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

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

00110001

00110010

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

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

00110010。

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

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

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

順序讀寫(xiě)方式:打開(kāi)文件時(shí)文件讀寫(xiě)指針指向文件頭或文件尾,讀寫(xiě)一個(gè)

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

后,讀寫(xiě)指針自動(dòng)指向下一個(gè)

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

或文件尾。程序無(wú)法修改文件讀寫(xiě)指針,文件指針始終往文件尾方向移動(dòng)。

data1data2data3data4datan-1

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

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

data1data2data3data4datan-1

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

標(biāo)準(zhǔn)I/O函數(shù)是基于I/O流的操作。C語(yǔ)言實(shí)現(xiàn)“字符流和BIT流特性差異的I/O設(shè)備”之間的轉(zhuǎn)換,即各種I/O設(shè)備的差異對(duì)于應(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流操作的文件稱為非流式文件。

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

無(wú)論是緩沖或者非緩沖的文件,其I/O操作的步驟如下,打開(kāi)文件時(shí),確定了文件讀寫(xiě)格式和讀寫(xiě)方式!

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

1411.2

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

目錄

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

不同的C編譯器關(guān)于FILE結(jié)構(gòu)類型的定義會(huì)略有差異,但提供的庫(kù)函數(shù)原型都是滿足C語(yǔ)言標(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)前讀寫(xiě)位置指針*/

unsigned

istemp;/*臨時(shí)文件描述符*/

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

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

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

externFILE_Cdecl

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

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

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

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

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

*/

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

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

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

目錄

文件打開(kāi)函數(shù)

fopen()

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

mode

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

filename

指定文件,返回

filename

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

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

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

FILE

*

fp;

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

]disk……test.dat11.3.1

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

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

如果文件打開(kāi)方式中不含有

“b”

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

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

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

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

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

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

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

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

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

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

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

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

FILE

*

fp;

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

fclose(fp);fp_streams[

]disk……test.dat20例11.3

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

#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方式打開(kāi)的、filename指定的文件,函數(shù)返回新打開(kāi)的文件指針。如果失敗返回NULL。FILE*_Cdecl

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

例如,按文本格式、順序?qū)懛绞酱蜷_(kāi)文件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中寫(xiě)字符,實(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)的任意打開(kāi)的文件都可以重定向。2311.3.3

基于字符的文件讀/寫(xiě)

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

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

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

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

從文件指針

stream

指向的文件中讀取一個(gè)字符,并將該字符作為unsignedchar類型轉(zhuǎn)換為整型值返回。遇到文件尾或讀操作出錯(cuò)時(shí)返回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ì)一個(gè)程序?qū)⒂脖P(pán)根目錄下的文本文件

“C:\test.dat”

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

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

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

fgetchar(void)函數(shù)

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

int

fgetchar(void){return

fgetc(stdin);}

將參數(shù)c轉(zhuǎn)換成為unsignedchar類型寫(xiě)到標(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

基于字符串的文件讀/寫(xiě)

C

提供的基于字符串的IO函數(shù)原型如下,其聲明在stdio.h之中。即使用時(shí),必須先用#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ù)是對(duì)標(biāo)準(zhǔn)文件或以文本格式打開(kāi)的文件進(jìn)行操作的!

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

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

s

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

將指針

s

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

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

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

文件的格式讀/寫(xiě)

C

提供的格式讀寫(xiě)的IO函數(shù)原型如下,其聲明在stdio.h中。即使用時(shí),必須先用#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ù)是對(duì)標(biāo)準(zhǔn)文件或以文本格式打開(kāi)的文件進(jìn)行操作的!后面4個(gè)函數(shù)功能和使用方法,與第3章的printf函數(shù)和scanf函數(shù)相同或類似,差異在于輸入輸出文件不同。

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

2911.3.6

文件的直接讀/寫(xiě)

C

提供的直接讀寫(xiě)的IO函數(shù)原型如下,其聲明在stdio.h中。即使用時(shí),必須先用#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ù)是對(duì)標(biāo)準(zhǔn)文件或以文本格式打開(kāi)的文件進(jìn)行操作的!

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

C

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

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

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

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

fwrite(constvoid*ptr,size_tsize,size_t

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

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

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

重要提示:實(shí)際上,不論文件是按文本格式,還是二進(jìn)制格式打開(kāi),函數(shù)fread和fwrite的讀寫(xiě)都是指定的字節(jié)數(shù)(=size×n),直接進(jìn)行讀寫(xiě)操作的,不做任何轉(zhuǎn)換。即函數(shù)fread和fwrite的讀寫(xiě)是二進(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中。即使用時(shí),必須先用#include<stdio.h>或#include"stdio.h"。

流式文件的隨機(jī)輸入輸出是指對(duì)文件的讀寫(xiě)可以從文件內(nèi)指定的位置進(jìn)行,而不必每次從頭順序開(kāi)始。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);

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

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

將stream指向的文件之當(dāng)前讀寫(xiě)指針,定位到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):對(duì)二進(jìn)制格式文件,基準(zhǔn)點(diǎn)的取值與偏移量無(wú)關(guān);對(duì)文本格式文件基準(zhǔn)點(diǎn)只能取

0

,而偏移量可以取

0

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

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

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

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

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

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

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

將文件指針

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

文件隨機(jī)讀/寫(xiě)

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

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

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

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

文件訪問(wèn)類函數(shù)

目錄

C標(biāo)準(zhǔn)規(guī)定了五個(gè)文件訪問(wèn)類操作函數(shù)如下。其中,前2個(gè)函數(shù)已經(jīng)討論過(guò),剩余3個(gè)函數(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(無(wú)緩沖)37int

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

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

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

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

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

3811.5.2

文件操作類函數(shù)

C標(biāo)準(zhǔn)規(guī)定了四個(gè)文件操作類函數(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)打開(kāi),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)建一個(gè)臨時(shí)二進(jìn)制文件,該臨時(shí)文件在文件關(guān)閉或程序結(jié)束時(shí)被自動(dòng)清除。如果調(diào)用成功,函數(shù)返回一個(gè)指向創(chuàng)建的臨時(shí)文件之文件指針,否則返回NULL。char*

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

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

出錯(cuò)檢測(cè)類函數(shù)

C標(biāo)準(zhǔn)規(guī)定了四個(gè)文件檢錯(cuò)類函數(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)前讀寫(xiě)位置指針*/

unsigned

istemp;/*臨時(shí)文件描述符*/

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

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

clearerr(FILE

*stream)函數(shù)

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

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論