語(yǔ)言-雜談程序i0流類庫(kù)_第1頁(yè)
語(yǔ)言-雜談程序i0流類庫(kù)_第2頁(yè)
語(yǔ)言-雜談程序i0流類庫(kù)_第3頁(yè)
語(yǔ)言-雜談程序i0流類庫(kù)_第4頁(yè)
語(yǔ)言-雜談程序i0流類庫(kù)_第5頁(yè)
已閱讀5頁(yè),還剩63頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第9章

I/O流類庫(kù)

9.1什么是流

9.2格式化輸入輸出

9.3文件I/O

9.4字符串流

9.1什么是流

C++中把數(shù)據(jù)之間的傳輸操作稱作流。在C++中,流既可以表示數(shù)據(jù)從內(nèi)存?zhèn)魉偷侥硞€(gè)載體或設(shè)備中,即輸出流;也可以表示數(shù)據(jù)從某個(gè)載體或設(shè)備傳送到內(nèi)存緩沖區(qū)變量中,即輸入流。在進(jìn)行I/O操作時(shí),首先打開操作,使流和文件發(fā)生聯(lián)系,建立聯(lián)系后的文件才允許數(shù)據(jù)流入或流出,輸入或輸出結(jié)束后,使用關(guān)閉操作使文件與流斷開聯(lián)系。

C++中所有流都是相同的,但文件可以不同。使用流以后,程序用流統(tǒng)一對(duì)各種計(jì)算機(jī)設(shè)備和文件進(jìn)行操作,使程序與設(shè)備、程序與文件無關(guān),從而提高了程序設(shè)計(jì)的通用性和靈活性。也就是說,無論與流相聯(lián)系的實(shí)際物理設(shè)備差別有多大,流都采用相同的方式運(yùn)行。

9.1.1預(yù)定義流

9.1.2C++的流類庫(kù)9.1.1預(yù)定義流

在程序開始運(yùn)行時(shí),C++會(huì)自動(dòng)打開4個(gè)流,這些流類庫(kù)的預(yù)定義流,如下表9.1所示。流含義所屬類庫(kù)默認(rèn)設(shè)備cin標(biāo)準(zhǔn)輸入iostream.h鍵盤cout標(biāo)準(zhǔn)輸出iostream.h顯示器cerr沒有被緩沖的標(biāo)準(zhǔn)錯(cuò)誤輸出iostream.h顯示器clog被緩沖了的標(biāo)準(zhǔn)錯(cuò)誤輸出iostream.h顯示器表9.1C++流庫(kù)的預(yù)定義流

1、coutcout是與標(biāo)準(zhǔn)輸出設(shè)備連接的預(yù)定義輸出流,稱為匯。C++的插入運(yùn)算符“<<”向輸出流發(fā)送字符。實(shí)際上,位于插入運(yùn)算符右側(cè)的字符串被存儲(chǔ)在“<<”左側(cè)的流中。例如:

cout<<name<<“”<<number<<‘\n’;cout是數(shù)據(jù)的目的地,插入運(yùn)算符“<<”把對(duì)象或文字?jǐn)?shù)據(jù)(字符串、數(shù)字或任何對(duì)象)傳送到cout。cout一般連接到標(biāo)準(zhǔn)輸出設(shè)備即顯示器(默認(rèn)設(shè)備)。2、cincin是與標(biāo)準(zhǔn)輸入設(shè)備連接的預(yù)定義輸入流,稱為源。它從輸入流中取出數(shù)據(jù),數(shù)據(jù)從輸入提取運(yùn)算符“>>”處流進(jìn)程序。為了保留輸入數(shù)據(jù),輸入語(yǔ)句要求有目的地址,即指定數(shù)據(jù)類型的存儲(chǔ)單元,例如:

inti;cin>>i;

這段代碼所進(jìn)行的操作是:提取運(yùn)算符“>>”從cin參數(shù)中提取一個(gè)整型輸入數(shù)據(jù),并存入一個(gè)對(duì)象(變量),在此例中即為整型數(shù)i。cin一般連接到標(biāo)準(zhǔn)輸入設(shè)備即鍵盤(默認(rèn)設(shè)備)。每種內(nèi)部類型都有內(nèi)部定義的提取運(yùn)算符,根據(jù)默認(rèn)定義,內(nèi)部類型的提取運(yùn)算符跳過空格,然后為當(dāng)前的類型讀入適當(dāng)?shù)臄?shù)據(jù)。3、cerrcerr類似標(biāo)準(zhǔn)錯(cuò)誤文件。cerr與cout的差別在于:(1)cerr是不能重定向的;(2)cerr不能被緩沖,它的輸出總是直接傳送到標(biāo)準(zhǔn)輸出設(shè)備上。錯(cuò)誤信息是寫到cerr的項(xiàng)。即使在各種其他輸出語(yǔ)句中,如果使用下列語(yǔ)句,則錯(cuò)誤信息“Error”總能保證在顯示器上顯示出來:4、clog

clog是不能重定向的,但是可以被緩沖。在某些系統(tǒng)中,由于緩沖,使用clog代替cerr可以改進(jìn)顯示速度:

clog<<“Error”<<“\n”;9.1.2C++的流類庫(kù)C++提供了一個(gè)流類庫(kù),流類庫(kù)由若干完成I/O操作的基礎(chǔ)類以及若干支持特定種類的源和目標(biāo)的I/O操作類組成。流類庫(kù)的基礎(chǔ)類利用繼承關(guān)系組織起來,其類層次如圖9.1所示,這些類的說明如表9.2所列。所有使用流類庫(kù)的程序必須用“#include”編譯指令將iostream.h包含進(jìn)來。ostrstreamostream_withassignistream_withassignistrstreamiostreamfstreamstrstreamofstreamifstreamostreamistreamios圖9.1I/O流類庫(kù)的類層次

表9.2I/O流類庫(kù)

9.2格式化輸入輸出

流類庫(kù)可用兩種方法控制數(shù)據(jù)的格式:使用流對(duì)象的成員函數(shù)和使用I/O控制符。

1、使用流對(duì)象的成員函數(shù)

2、用控制符

manipulators(控制符)是在頭文件iomanip.h中定義的對(duì)象,與成員函數(shù)調(diào)用效果一樣??刂品膬?yōu)點(diǎn)是程序可以直接將它們插入流中,不必單獨(dú)調(diào)用。例9.1下面的程序改變輸出精度#include<iostream.h>voidfn(floatinterest,floatamount){cout<<“RMBamount=”;cout.precision(2);//置有效位數(shù)為2位

cout<<amount;cout<<“\ntheinterest=”;cout.precision(4);//置有效位數(shù)為4位

cout<<interest<<endl;}voidmain(){floatf1=29.41560067;floatf2=12.567188;fn(f1,f2);}運(yùn)行結(jié)果為:RMBamount=13theinterest=29.42precision()為cout對(duì)象的成員函數(shù),在要求輸出一定精度的數(shù)據(jù)之前,先調(diào)用這個(gè)精度設(shè)置成員函數(shù)。例9.2用控制符設(shè)置小數(shù)精度,重寫例9.1(考慮兩程序的執(zhí)行結(jié)果)#include<iostream.h>#include<iomanip.h>voidfn(floatinterest,floatamount){cout<<“RMBamount=”<<setprecision(2)<<amount;cout<<“\ntheinterest=”<<setprecision(4)<<interest<<endl;}voidmain(){floatf1=29.41560067;floatf2=12.567188;fn(f1,f2);}常用控制符和流格式控制成員函數(shù)如表9.3所示。表9.3常用控制符與流控制成員函數(shù)

控制符和流成員函數(shù)相對(duì)應(yīng),它們用法不同,但作用相同。其中setw(n)或width(n)很特別,他們?cè)谙乱粋€(gè)域輸出后,又回到原先的默認(rèn)值。例9.3輸出下面的兩個(gè)數(shù)#include<iostream.h>#include<iomanip.h>voidmain(){cout.width(8);cout<<10<<20<<endl;}運(yùn)行結(jié)果為:______1020運(yùn)行結(jié)果中的下橫線表示空格。整數(shù)20并沒有按寬度8輸出。例9.4給出下列程序的執(zhí)行結(jié)果

#include<iostream.h>#include<iomanip.h>voidmain(){for(intn=1;n<8;n++)cout<<setfill(‘’)<<setw(n)<<“”<<setfill(‘a(chǎn)’)<<setw(15-2*n)<<“a”<<endl;}運(yùn)行結(jié)果為:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9.3文件I/O

在C++中,把文件看成是由一系列字節(jié)所構(gòu)成的字節(jié)串,稱為流式文件,對(duì)文件中數(shù)據(jù)的操作(輸入/輸出)通常是逐個(gè)字節(jié)順序進(jìn)行。在對(duì)文件數(shù)據(jù)進(jìn)行讀寫前,首先要打開文件。打開文件的目的是:在程序內(nèi)部的一個(gè)表示文件的變量與外部的一個(gè)具體文件之間建立聯(lián)系。每個(gè)打開的文件都有一個(gè)內(nèi)部的位置指針,它指出文件的當(dāng)前讀寫位置。

9.3.1基于I/O函數(shù)庫(kù)的文件I/O

9.3.2基于I/O類庫(kù)的文件I/O9.3.1基于I/O函數(shù)庫(kù)的文件I/OC++從C語(yǔ)言標(biāo)準(zhǔn)庫(kù)保留下來的輸入/輸出函數(shù)庫(kù)中包含了對(duì)文件進(jìn)行輸入/輸出操作的函數(shù)。程序中應(yīng)有下面的文件包含命令:

#include<cstdio>//或#include<stdio.h>1、文件的輸出操作

(1)

打開文件。打開外部文件輸出數(shù)據(jù)要用下面的函數(shù)fopen來實(shí)現(xiàn):FILE*fopen(constchar*filename,constchar*mode);//打開方式

其中,filename是要打開的外部文件名;mode表示打開方式,它可以是:“w”:打開一個(gè)外部文件用于寫操作,如果外部文件已存在,則首先把它的內(nèi)容清除;否則,先創(chuàng)建該外部文件?!癮”:打開一個(gè)外部文件用于添加(從文件末尾)操作。如果外部文件不存在,則先創(chuàng)建該外部文件。(2)輸出操作。文件打開成功后就可以往文件中寫入數(shù)據(jù)了。往文件中寫入數(shù)據(jù)的函數(shù)主要有以下幾個(gè)://輸出一個(gè)字符,輸出成功時(shí)返回輸出的字符。intfputc(intc,FILE*stream);//輸出一個(gè)字符串,輸出成功時(shí)返回一個(gè)非負(fù)整數(shù)。intfputs(constchar*string,FILE*stream);//輸出基本類型數(shù)據(jù),返回輸出的字符數(shù)。intfprintf(FILE*stream,constchar*format[,argument]…);//按字節(jié)輸出數(shù)據(jù)。參數(shù)size為字節(jié)塊的尺寸;count為字節(jié)塊的個(gè)數(shù)。返回實(shí)際輸出的字節(jié)塊的個(gè)數(shù)。

size_fwrite(constvoid*buffer,size_tsize,size_tcount,FILE*stream);

(3)關(guān)閉文件。文件操作結(jié)束后需要執(zhí)行關(guān)閉操作:

intfclose(FILE*stream);//關(guān)閉文件上面的函數(shù)返回0表示成功。例9.5從鍵盤輸入一批學(xué)生的成績(jī)信息,并把它們以文本格式存入外部文件scores.txt。#include<cstdio>usingnamespacestd;intmain(){FILE*fp=fopen(“d:\\scores.txt”,“w”);//以文本方式打開文件用于輸出

if(fp==NULL)//判斷文件打開是否成功

{printf(“打開文件失??!\n”);return–1;}charid[11],name[9];intnum_of_courses,score;printf(“請(qǐng)輸入學(xué)號(hào)、姓名、選課數(shù)及各門課成績(jī)(以學(xué)號(hào)為‘E’結(jié)束):\n”);scanf(“%10s”,id);//讀入第一個(gè)學(xué)生的學(xué)號(hào)while(id[0]!=’E’)//判斷輸入是否結(jié)束

{scanf(“%8s”,name);//讀入姓名

scanf(“%d”,&num_of_courses);//讀入選課數(shù)

fprintf(fp,“%s%s%d”,id,name,num_of_courses);//把學(xué)號(hào)、姓名和選課數(shù)輸出到文件

for(inti=0;i<num_of_courses;i++)//循環(huán)讀入各門課成績(jī)并輸出到文件

{scanf(“%d”,&score); fprintf(fp,“%d”,score); }fputc(‘\n’,fp);//輸出一個(gè)換行符到文件

scanf(fp);//讀入下一個(gè)學(xué)生的學(xué)號(hào)

}fclose(fp);}上面程序的輸入格式為:001張三470808590↙002李四58560759080↙……E↙例9.6從鍵盤讀入一批學(xué)生的信息,并把它們以二進(jìn)制格式存入外部文件students.dat

。#include<cstdio>usingnamespacestd;enumSex{MALE,FEMALE};structDate{intyear;intmonth;intday;};EnumMajor{MATHEMATICS,PHYSICS,CHEMISTRY,COMPUTER,GEOGRAPHY,ASTRONOMY,ENGLISH,CHINESE,PHILOSOPHY};structstudent{charid[11];charname[9];Sexsex;Datebirth_date;charbirth_place[40];Majormajor;};intmain(){FILE*fp=fopen(“d:\\students.dat”,“wb”);//以二進(jìn)制方式打開文件用于輸出

if(fp==NULL)//判斷文件打開是否成功

{printf(“打開文件失??!\n”); return–1; }Studentst;printf(“輸入學(xué)號(hào)、姓名、性別、出生日期、出生地和專業(yè)(以學(xué)號(hào)為‘E’結(jié)束)\n”);scanf(“%10s”,st.id);//讀入第一個(gè)學(xué)生的學(xué)號(hào)while(st.id[0]!=’E’){……//讀入姓名、性別、出生日期、出生地和專業(yè)到變量st中fwrite(&st,sizeof(st),1,fp);//以二進(jìn)制格式輸出變量st的值到文件

scanf(“%10s”,st.id);//讀入下一個(gè)學(xué)生的學(xué)號(hào)}fclose(fp);//關(guān)閉文件}2、文件的輸入操作

(1)打開文件。打開外部文件輸入數(shù)據(jù)要用下面的函數(shù)fopen來實(shí)現(xiàn):

FILE*fp=fopen(constchar*filename,constchar*mode);其中,filename是要打開的外部文件名;mode是打開方式,它可以是“r”,表示打開一個(gè)外部文件用于讀操作,這時(shí),外部文件必須存在,否則打開文件失敗。

(2)輸入操作。從文件中輸入數(shù)據(jù)的函數(shù)主要有以下幾個(gè):

//輸入一個(gè)字符,返回字符的編碼。

intfgetc(FILE*stream);

//輸入一個(gè)字符串,函數(shù)正常結(jié)束時(shí)返回string的值,否則返回NULL。

char*fgets(char*string,intn,F(xiàn)ILE*stream);

//輸入基本類型的數(shù)據(jù),返回值表示讀入并存儲(chǔ)的數(shù)據(jù)個(gè)數(shù)。

intfscanf(FILE*stream,constchar*format[,argument]…);

//按字節(jié)輸入數(shù)據(jù)。參數(shù)size為字節(jié)塊的尺寸;

count為字節(jié)塊的個(gè)數(shù)。返回值表示讀入的字節(jié)塊的個(gè)數(shù)。

size_tfread(constvoid*buffer,size_tsize,size_tcount,FILE*stream);//判斷文件結(jié)束.當(dāng)文件位置指針在文件末尾時(shí),進(jìn)行一次讀操作之后將使得feof返回非零

(true)。

intfeof(FILE*stream);(3)關(guān)閉文件。文件操作結(jié)束時(shí)應(yīng)關(guān)閉打開的文件:

fclose(FILE*stream);例9.7從例9.5輸出的文件中讀入數(shù)據(jù),計(jì)算每個(gè)學(xué)生的平均成績(jī)并輸出到顯示器。本章例9.5輸出的文件是以文本方式組織的,因此,讀入該文件數(shù)據(jù)時(shí)也要以文本方式進(jìn)行。#include<cstdio>usingnamespacestd;intmain(){FILE*fp=fopen(“d:\\scores.txt”,“r”);//以文本方式打開文件用于輸入

If(fp==NULL)//判斷文件打開是否成功

{printf(“打開文件失??!\n”);return-1;}charid[11],name[9];intnum_of_courses,score,total;fscanf(fp,“%10s”,id);//讀入第一個(gè)學(xué)生的學(xué)號(hào)while(!feof(fp))//判斷文件結(jié)束標(biāo)記{fscanf(fp,“%8s”,name);//讀入姓名

fscanf(fp,“%d”,&num_of_courses);//讀入選課數(shù)

total=0;for(inti=0;i<num_of_courses;i++)//循環(huán)讀入各門課成績(jī)并加到total上去

{fscanf(fp,“%d”,&score); total+=score;}printf(“%s,%s,%d\n”,id,name,total/num_of_courses);//輸出結(jié)果fscanf(fp,“%10s”,id);//讀入下一個(gè)學(xué)生的學(xué)號(hào)

} fclose(fp);//關(guān)閉文件

}例9.8從例9.6輸出的文件中讀入數(shù)據(jù),統(tǒng)計(jì)男生的人數(shù)。本章例9.6輸出的文件是以二進(jìn)制方式組織的,因此,讀入該文件數(shù)據(jù)時(shí)也要以二進(jìn)制方式進(jìn)行。#include<cstdio>usingnamespacestd;……//省略了Sex、Date、Major以及Student的定義。intmain(){FILE*fp=fopen(“d:\\students.dat”,“rb”);//以二進(jìn)制方式打開文件用于輸入

If(fp==NULL)//判斷文件打開是否成功

{printf(“打開文件失?。n”);return-1;}Studentst;

intcount=0;fread(&st,sizeof(st),1,fp);//讀入第一個(gè)學(xué)生的信息while(!feof(fp)){if(st.sex==MALE)count++;fread(&st,sizeof(st),1,fp);//讀入下一個(gè)學(xué)生的信息}printf(“男生的人數(shù)是:%d\n”,count);fclose(fp);}3、文件的輸入/輸出操作以“w”或“a”方式打開的文件只能對(duì)其進(jìn)行輸出操作;以“r”方式打開的文件只能對(duì)其進(jìn)行輸入操作。如果需要打開一個(gè)文件既能用于輸出又能用于輸入(讀寫方式),則應(yīng)采用下面的函數(shù)打開文件:

FILE*fopen(constchar*filename,constchar*mode);其中,mode可以是:·

“r+”:打開一個(gè)外部文件用于讀/寫操作。文件必須存在。·

“w+”:打開一個(gè)外部文件用于讀/寫操作。如果文件不存在,則首先創(chuàng)建一個(gè)空文件,否則,首先清空已有文件中的內(nèi)容?!?/p>

“a+”:打開一個(gè)外部文件用于讀/添加操作。如果文件不存在,則首先創(chuàng)建一個(gè)空文件。以這種方式打開的文件,輸出操作總是在文件尾進(jìn)行。另外,在r+、w+或a+的后面還可以加上t或b,以區(qū)別文本或二進(jìn)制方式打開文件。4、隨機(jī)輸入/輸出每個(gè)打開的文件都有一個(gè)位置指針,指向當(dāng)前讀/寫位置,每讀入或?qū)懗鲆粋€(gè)字符,文件的位置指針都會(huì)自動(dòng)往后移動(dòng)一個(gè)位置。除了自動(dòng)移動(dòng)文件位置指針外,文件位置指針也可以用一個(gè)函數(shù)來顯式地指定:

intfseek(FILE*stream,longoffset,intorigin);//顯式地指定位置指針的位置其中,origin指出參考位置,它可以是SEEK_CUR(當(dāng)前位置)、SEEK-_END(文件末尾)或SEEK_SET(文件頭);offset為移動(dòng)的字節(jié)數(shù)(偏移量),它可以為正值(向后移動(dòng))或負(fù)值(向前移動(dòng))。

Longftell(FILE*stream);//返回位置指針的位置。例9.9讀入例9.6生成的文件(students.dat)中的第二個(gè)學(xué)生的信息,把該學(xué)生的專業(yè)修改成COMPUTER,然后把它寫回文件中。(考慮程序的執(zhí)行結(jié)果)

#include<cstdio>usingnamespacestd;……//省略了Sex、Date、Major以及Student的定義。intmain(){FILE*fp=fopen(“d:\\students.dat”,“r+b”);//以二進(jìn)制方式打開文件用于輸入/輸出

If(fp==NULL)//判斷文件打開是否成功

{printf(“打開文件失?。n”);return-1;}studentst;if(fseek(fp,sizeof(st),SEEK_SET)==0)//文件位置指針指向第二個(gè)學(xué)生數(shù)據(jù){fread(&st,sizeof(st),1,fp);//讀入第二個(gè)學(xué)生數(shù)據(jù),文件位置指針移至下一個(gè)學(xué)生數(shù)據(jù) PUTER;//修改第二個(gè)學(xué)生數(shù)據(jù)的專業(yè) fseek(fp,-sizeof(st),SEEK_CUR);//文件位置指針指回第二個(gè)學(xué)生數(shù)據(jù) fwrite(&st,sizeof(st),1,fp);//修改后的第二個(gè)學(xué)生數(shù)據(jù)寫回文件}fclose(fp);//關(guān)閉文件。}9.3.2基于I/O類庫(kù)的文件I/O

除了用庫(kù)函數(shù)進(jìn)行文件輸入/輸出外,還可以利用C++的I/O類庫(kù)進(jìn)行文件的輸入/輸出。在利用I/O類庫(kù)中的類進(jìn)行外部文件的輸入/輸出時(shí),程序中需要下面的包含命令:

#include<iostream> #include<fstream>

1、輸出首先創(chuàng)建一個(gè)ofstream類(是ostream類的派生類)的對(duì)象,使之與某個(gè)外部文件建立聯(lián)系。建立ofstream類的對(duì)象與外部文件聯(lián)系的方式有兩種:直接方式和間接方式。直接方式是在創(chuàng)建ofstream類的對(duì)象時(shí)指出外部文件名和打開方式,例如:

ofstreamout_file(<文件名>,<打開方式>);

間接方式是在創(chuàng)建了ofstream類的對(duì)象之后,調(diào)用ofstream的一個(gè)成員函數(shù)open來指出與外部文件的聯(lián)系。例如: ofstreamout_file; out_file.open(<文件名>,<打開方式>);其中,<文件名>表示文件對(duì)象out_file對(duì)應(yīng)的外部文件名,<打開方式>可以是:·ios::out,含義與fopen的打開方式“w”相同?!os::app,含義與fopen的打開方式“a”相同。

另外,<打開方式>還可以是上面的值與ios::binary按位或(|)操作的結(jié)果,它表示按二進(jìn)制方式打開文件。默認(rèn)的方式是文本方式。例9.10用I/O類庫(kù)的類實(shí)現(xiàn)例9.5的程序功能。在本例中,我們用類StudentScores來描述學(xué)生的成績(jī)數(shù)據(jù),通過重載操作符“<<”和“>>”來實(shí)現(xiàn)對(duì)StudentScores類的數(shù)據(jù)的輸入/輸出操作。

#include<iostream> #include<fstream> #include<iomanip> usingnamespacestd;constintMAX_NUM_OF_COURSES=30;constintMAX_ID_LEN=10;constintMAX_NAME_LEN=8;classStudentScores{public:StudentScores(){initialized=false;}booldata_is_ok()const{returninitialized;}private:intscores[MAX_NUM_OF_COURSES],num_of_courses;charid[MAX_ID_LEN+1],name[MAX_NAME_LEN+1];boolinitialized;//表示學(xué)生成績(jī)數(shù)據(jù)是否被成功讀入friendistream&operator>>(istream&in,StudentScores&x);friendostream&operator>>(ostream&out,StudentScores&x);}istream&operator>>(istream&in,StudentScores&x){if(&in==&cin)//從鍵盤輸入時(shí)需要給出提示

cout<<“請(qǐng)輸入學(xué)號(hào)、姓名、選課數(shù)及各門課成績(jī)(以學(xué)號(hào)為‘E’結(jié)束):\n”;in>>setw(11)>>x.id;//讀入學(xué)號(hào)if(in.eof()||x.id[0]==‘E’)//判斷結(jié)束標(biāo)記{x.initialized=false;returnin;}in>>setw(9)>>;//讀入姓名in>>x.num_of_courses;//讀入選課數(shù)if(x.num_of_course>MAX_NUM_OF_COURSES){x.initialized=false;returnin;}for(inti=0;i<x.num_of_courses;i++)//循環(huán)讀入各門課成績(jī)

in>>x.scores[i];x.initialized=true;returnin;}ostream&operator>>(ostream&out,StudentScores&x){out<<x.id<<‘’//輸出學(xué)號(hào)

<<<<‘’//輸出姓名

<<x.num_of_courses;//輸出選課數(shù)for(inti=0;i<x.num_of_courses;i++)//循環(huán)輸出各門課成績(jī)out<<‘’<<x.scores[i];returnout;}intmain(){ofstreamout_file(“d:\\scores.txt”,ios::out);//以文本方式打開文件用于輸出

if(!out_file)//判斷文件打開是否成功

{cerr<<“打開文件失敗!\n”;return-1;}StudentScoresst;cin>>st;//從標(biāo)準(zhǔn)輸入設(shè)備讀入第一個(gè)學(xué)生的選課信息while(st.data_is_ok())//判斷輸入是否結(jié)束{out_file<<st<<endl;//往文件中寫入學(xué)生選課信息cin>>st;//從標(biāo)準(zhǔn)輸入設(shè)備讀入下一個(gè)學(xué)生的選課信息}out_file.close();//關(guān)閉文件return0;}2、輸入首先創(chuàng)建一個(gè)ifstream類(istream類的派生類)的對(duì)象,并與外部文件建立聯(lián)系。例如:

ifstreamin_file(<文件名>,<打開方式>);//以直接方式建立與外部文件的聯(lián)系或

ifstreamin_file; in_file.open(<文件名>,<打開方式>);//以間接方式建立與外部文件的聯(lián)系

其中,<文件名>是對(duì)象in_file對(duì)應(yīng)的外部文件名,<打開方式>可以是ios::in,它的含義與fopen的打開方式“r”相同,也可以把它與ios::binary通過按位或(|)操作實(shí)現(xiàn)二進(jìn)制打開方式。默認(rèn)的方式是文本方式。 在進(jìn)行輸入操作前也必須對(duì)文件打開是否成功進(jìn)行判斷,判斷方式與輸出文件對(duì)象相同。

例9.11用I/O類庫(kù)中的類實(shí)現(xiàn)例9.7中程序的功能。

#include<iostream> #include<fstream> #include<iomanip> usingnamespacestd; classStduentScores {public: StduentScores(){initialized=false;} booldata_is_ok(){returninitialized;} char*get_id()const{returnid;} constchar*get_name()const{returnname;} intaverage_score()const {inttotal=0; for(inti=0;i<num_of_courses;i++) total+=scores[i]; returntotal/num_of_courses; } private: intscores[MAX_NUM_OF_COURSES],num_of_courses;

charid[MAX_ID_LEN+1],name[MAX_NAME_LEN+1]; boolinitialized; friendistream&operator>>(istream&in,StduentScores&x); friendostream&operator<<(ostream&out,StduentScores&x); }; ……//操作符“>>”和“<<”的重載與例9.10完全相同。

intmain() {ifstreamin_file(“d:\\scores.txt”,ios::in);//以文本方式打開文件用于輸入

if(!in_file)//判斷文件打開是否成功

{cerr<<“打開文件失?。n”;return-1;}cout<<“學(xué)號(hào),姓名,平均成績(jī):\n”;StudentScoresst;in_file>>st;while(st.data_is_ok()){cout<<st.get_id()<<‘,’

<<st.get_name()<<‘,’

<<st.average_score()<<endl;in_file>>st;}in_file.close();//關(guān)閉文件。}3、輸入/輸出如果需要打開一個(gè)既能讀入數(shù)據(jù)也能輸出數(shù)據(jù)的文件,則需要?jiǎng)?chuàng)建一個(gè)fstream類的對(duì)象(類fstream是類iostream的派生類)。在創(chuàng)建fstream類的對(duì)象并建立與外部文件聯(lián)系時(shí),文件打開方式應(yīng)為ios::in|ios::out(可在文件任意位置寫)或ios::in|ios::app(只能在文件末尾寫)。例如,下面打開的文件既能讀入又能寫出數(shù)據(jù):

fstreamio_file(“d:\\test.txt”,ios::in|ios::out);

一般來說,以讀寫方式打開的文件,數(shù)據(jù)的讀寫操作要與下面介紹的seekp或seekg操作配合使用。4、隨機(jī)存取文件為了能夠隨機(jī)讀寫文件中的數(shù)據(jù),必須要顯式地指出讀寫的位置。對(duì)于以輸入方式打開的文件,可用下面的操作來指定文件內(nèi)部的指針位置:istream&istream::seekg(<位置>);//指定絕對(duì)位置istream&istream::seekg(<偏移量>,<參照位置>);//指定相對(duì)位置streamposistream::tellg();//獲得指針位置對(duì)于輸出文件,可以用下面的操作來指定文件內(nèi)部的指針位置:ostream&ostream::seekp(<位置>);//指定絕對(duì)位置ostream&ostream::seekp(<偏移量>,<參照位置>);//指定相對(duì)位置streamposostream::tellp();//獲得指針位置 在上面的函數(shù)中,<參照位置>可以是ios::beg(文件頭)、ios::cur(當(dāng)前位置)和ios::end(文件尾)。例9.12

根據(jù)學(xué)號(hào)在例9.6的程序所生成的數(shù)據(jù)文件(students.dat)中查找某個(gè)學(xué)生信息并修改該學(xué)生的專業(yè)。

#include<iostream> #include<fstream> #include<iomanip> #include<cstring>usingnamespacestd;……//這里省略了Student、Date、Sex以及Major的定義。classStudentsFile{public:

StudentsFile(constcharfilename[]); {io_file.open(filename,ios::in|ios::out|ios::binary);} ~StudentsFile(){io_file.close();} boolis_open()const{returnio_file.is_open();}intfind(charid[],Student&st)//查找學(xué)號(hào)為id的學(xué)生

{intindex=0; io_file.seekg(0); io_file.read((char*)&st,sizeof(st));//讀入第一個(gè)學(xué)生的數(shù)據(jù)

while(!io_file.eof())//循環(huán)查找學(xué)號(hào)為id的學(xué)生

{if(strcmp(st.id,id)==0) returnindex;//返回找到的學(xué)生在文件中的位置

index++; io_file.read((char*)&st,sizeof(st));//讀入下一個(gè)學(xué)生的數(shù)據(jù)

} ruturn–1;//沒有找到返回-1 }

boolput_at(intindex,Student&st)//更新文件中指定位置上的學(xué)生信息

{io_file.seekp(index*sizeof(st));//文件位置指針定位

if(io_file.fail())returnfalse; io_file.write((cha

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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)論