文件和結構體(C++版)_第1頁
文件和結構體(C++版)_第2頁
文件和結構體(C++版)_第3頁
文件和結構體(C++版)_第4頁
文件和結構體(C++版)_第5頁
已閱讀5頁,還剩14頁未讀 繼續免費閱讀

下載本文檔

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

文檔簡介

第七章文件與結構體文件是根據特定的目的而收集在一起的有關數據的集合。C++把每一個文件都看成是一個有序的字節流,每個文件都以文件結束標志結束,如果要操作某個文件,程序必須首先打開該文件。當一個文件被打開后,該文件就和一個流關聯起來,這里的流實際上是一個字節序列。C++將文件分為文本文件和二進制文件。二進制文件一般含有特殊的格式或計算機代碼,如圖文件和可執行文件等。文本文件則是可以用任何文字處理程序閱讀和編輯的簡單ASCII文件。下面我們學習如何編寫C++代碼來實現對文本文件的輸入和輸出。

第一節文件操作

C++語言提供了一批用于文件操作的標準函數,本節不是介紹文件打開函數fopen,而是介紹另一個函數freopen,它們都包含于標準庫cstdio中,文件操作基本步驟如下:

(1)打開文件,將文件指針指向文件,決定打開文件類型;

(2)對文件進行讀、寫操作;

(3)在使用完文件后,關閉文件。一、重定向版【命令格式】FILE*freopen(constchar*filename,constchar*mode,FILE*stream);【參數說明】

filename:

要打開的文件名

mode:文件打開的模式,和fopen中的模式(r/w)相同

stream:

文件指針,通常使用標準流文件(stdin/stdout/stderr)

其中stdin是標準輸入流,默認為鍵盤;stdout是標準輸出流,默認為屏幕;stderr是標準錯誤流,一般把屏幕設為默認。通過調用freopen,就可以修改標準流文件的默認值,實現重定向。

【使用方法】

因為文件指針使用的是標準流文件,因此我們可以不定義文件指針。接下來我們使用freopen()函數以只讀方式r(read)打開輸入文件slyar.in。格式:freopen("slyar.in","r",stdin);

然后使用freopen()函數以寫入方式w(write)打開輸出文件slyar.out。

格式:freopen("slyar.out","w",stdout);

接下來的事情就是使用freopen()函數的優點了,我們不再需要修改scanf,printf,cin和cout。而是維持代碼的原樣就可以了。因為freopen()函數重定向了標準流,使其指向前面指定的文件,省時省力。最后只要使用fclose關閉輸入文件和輸出文件即可。

格式:fclose(stdin);fclose(stdout);

若要恢復句柄,可以重新打開標準控制臺設備文件,只是這個設備文件的名字是與操作系統相關的。

格式:freopen("CON","r",stdin);代碼模版:#include<cstdio>//使用freopen語句,須調用cstdio庫intmain(){freopen("slyar.in","r",stdin);freopen("slyar.out","w",stdout);

/*中間按原樣寫代碼,什么都不用修改*/

fclose(stdin);fclose(stdout);return0;}例9.1從in.txt文件中讀入數據,把它們的和保存out.txt文件中。#include<cstdio>intmain(){freopen("in.txt","r",stdin);//定義輸入文件名freopen("out.txt","w",stdout);//定義輸出文件名inttemp,sum=0;while(scanf("%d",&temp)==1)//(cin>>temp)從輸入文件中讀入數據//在C++中非0為真{sum=sum+temp;}printf("%d\n",sum);//cout<<sum<<endl;fclose(stdin);fclose(stdout);//關閉文件,可省略return0;}in.txt數據:12345out.txt結果:15說明:while(fin>>temp)和(scanf("%d",&temp)==1)主要是用于判斷數據是否已經讀完,以便及時終止循環。還可以用成員函數eof來判斷是否達到數據流的末尾。對scanf、printf和cin、cout語句都適用。二、fopen版

重定向用起來很方便,但并不是所有算法競賽都允許讀寫文件。甚至有的競賽允許訪問文件,但不允許使用freopen這樣的重定向方式讀寫文件,可以使用fopen版,對scanf和printf語句適用。程序如下:#include<cstdio>usingnamespacestd;intmain(){FILE*fin,*fout;fin=fopen("in.txt","rb");//定義輸入文件名fout=fopen("out.txt","wb");//定義輸出文件名inttemp,sum=0;while(fscanf(fin,"%d",&temp)==1)//從輸入文件中讀入數據{sum=sum+temp;}fprintf(fout,"%d\n",sum);//cout<<sum<<endl;fclose(fin);fclose(fout);//關閉文件,可省略return0;}

先聲明變量fin和fout(暫且不用管FILE*為何物),把scanf改成fscanf,第一個參數為fin;把printf改成fprintf,第一個參數為fout,最后執行fclose,關閉兩個文件。重定向和fopen兩種方法各有優劣。重定向的方法寫起來簡單、自然,但是不能同時讀寫文件和標準輸入輸出;fopen的寫法稍顯繁瑣,但是靈活性比較大(例如可以反復打開并讀寫文件)。順便說一句,如果把fopen版的程序改成讀寫標準輸入輸出,只需賦值fin=stdin;fout=stdout;即可,不要調用fopen和fclose。程序如下:#include<cstdio>usingnamespacestd;intmain(){FILE*fin,*fout;fin=stdin;fout=stdout;/*本處語句同上*/fprintf(fout,"%d\n",sum);return0;}三、文件輸入輸出流

在C++中,文件輸入流(ifstream)和文件輸出流(ofstream)的類,它們的默認輸入輸出設備都是磁盤文件。C++可以在創建對象時,設定輸入或輸出到哪個文件。由于這些類的定義是在fstream中進行的,因此,在使用這此類進行輸入輸出操作時,必須要在程序的首部利用#include指令包進fstream頭文件。例如:若想用fin作為輸入對象,fout作為輸出對象,則可以使用如下定義:ifstreamfin("輸入文件名.擴展名");ofstreamfout("輸出文件名.擴展名");程序如下:#include<fstream>//使用文件輸入輸出流,對cin、cout語句適用usingnamespacestd;intmain(){ifstreamfin("in.txt");//定義輸入文件名ofstreamfout("out.txt");//定義輸出文件名inttemp,sum=0;while(fin>>temp)sum=sum+temp;//從輸入文件中讀入數據fout<<sum<<endl;fin.close();fout.close();//關閉文件,可省略return0;}如果想再次使用cin和cout,是否要逐個把程序中的所有fin和fout替換為cin和cout?不用這么麻煩,只需要把fin和fout的聲明語句去掉,并加上這樣兩行即可:#definefincin#definefoutcout用條件編譯,還可以讓程序在本機上讀寫標準輸入輸出,比賽測試時讀寫文件(請讀者自行實驗)。第二節結構體在實際問題中,一組數據往往具有不同的數據類型。例如,人口大普查時,我們需要記錄每一位公民的姓名,年齡,性別,住址,身份證號碼。這些信息分別要用整型,字符型,字符串型來記錄。為了解決問題,C++語言給出了另一種構造數據類型——“結構體”,它在數據存儲方面相當于其他高級語言中的記錄,但它有著面向對象的優勢。

7.2.1結構體定義和操作

1.定義結構體及結構體變量結構體變量的定義有兩種方式:

定義結構體的同時定義結構體變量

struct結構體名{ //其中struct是關鍵字 成員表 //可以有多個成員 成員函數 //可以有多個成員函數,也可以沒有

}結構體變量表; //可以同時定義多個結構體變量

結構體變量名列表的各個變量用“,”隔開。例如:

structDATA{

inta[2]; //成員為一個數組

intc;

}data_a,data_b;

當然,我們也可以先定義結構體再定義結構體變量

struct結構體名{ 成員表 成員函數};結構體名結構體變量表;//同樣可以同時定義多個結構體變量例如:

structDATA{

inta[2];

intc;

};

DATAdata_a,data_b;//這種定義方式與上一種方式的效果是相同的在定義結構體變量時注意,結構體變量名和結構體名不能相同。在定義結構體時,系統對之不分配實際內存。只有定義結構體變量時,系統才為其分配內存。

2.成員調用結構體變量與各個成員之間引用的一般形式為:結構體變量名.成員名對于上面定義的結構體變量,我們可以這樣操作:

cin>>data_a.a[0]>>data_a.a[1];//一般情況下不能寫cin>>data_a;

inta=data_a.a[0]+data_a.a[1];//就像用整形變量一樣用a[0]、a[1]

data_b=data_a; //結構體之間的相互賦值是合法的

data_a.c=0; //就如同給整形變量賦值實際上結構體成員的操作與該成員類型所具有的操作是一致的。

成員運算符“.”在存取成員數值時使用,其優先級最高,并具有左結合性。在處理包含結構體的結構體時,可記作:strua.strub.membb這說名結構體變量strua有結構體成員strub;結構體變量strub有成員membb。

3.成員函數調用結構體成員函數調用的一般形式為:結構體變量名.成員函數

結構體成員函數默認將結構體變量作為引用參數。

7.2.2結構體操作實例現在,我們先定義一個簡單的結構體,這個結構體將用來記錄一個學生的大致情況,所以它的成員應該有學號、姓名、性別、年齡、成績、家庭住址等。

#include<iostream>

usingnamespacestd;

structstudent{

intnum; //學號

charname[21]; //姓名

charsex; //性別

intage; //年齡

floatscore; //成績

charaddress[51]; //家庭住址

};//此處不可忽略分號

structstudenta,b;

intmain()

{

cin>>a.num>>>>a.sex>>a.age>>a.score>>a.address;

cin>>b.num>>>>b.sex>>b.age>>b.score>>b.address;

cout<<a.num<<''<<<<''<<a.sex<<''<<a.age<<''<<a.score<<''<<a.address<<endl;

cout<<b.num<<''<<<<''<<b.sex<<''<<b.age<<''<<b.score<<''<<b.address<<endl;

return0;

}

這里再舉出一個的例子,希望競賽學子能夠舉一反三,從中受益。

#include<iostream>

usingnamespacestd;

structDATA{

inta[2];//成員為一個數組

intc; //用來計算總和

intmax()//定義成員函數

{

returna[0]>a[1]?a[0]:a[1];

溫馨提示

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

評論

0/150

提交評論