標準IO庫:
標準庫定義了一族類型,支援對檔案和控制視窗等裝置的讀寫,還使得string對象能夠像檔案一樣操作。採用繼承來實現。
流:是以位元組方式對資料從源到目標進行傳遞的一種描述。
輸入資料流:指從輸入裝置到記憶體中位元組的傳遞;
輸出資料流:指從記憶體到輸出裝置中位元組的傳遞;
iostream類庫的介面對應的標頭檔:
標頭檔iostream包含所有i/o流所需的基本資料,並定義有四個標準i/o流對象:
cin:標準輸入資料流對象(與標準輸入裝置串連)
cout :標準輸出資料流(與標準輸出裝置串連)
cerr :非緩衝的標準錯誤流(預設裝置為顯示器)
clog :經緩衝的標準錯誤流(預設裝置為印表機)
iostream繼承層次:
目前,所描述的流類(stream class)讀寫的是由char類型組成的流。
IO對象不可複製或者賦值:
標準庫類型不允許做複製或者賦值操作。這個要求說明:
首先,在流對象不能在容器類型(如vector)中儲存,因為容器類型中只能儲存支援複製的元素類型。
其次,形參或者傳回型別不能為流類型。如果非要傳遞或者返回IO對象,那麼必須傳遞或返回指向該對象的指標或者引用。
條件狀態:
IO標準庫管理一系列的條件狀態,用來標記給定的IO對象是否處於可用狀態。
流必須處於無錯誤狀態,才可以用於輸入或者輸出。檢查流是否可用的最簡單方法是檢查它的真值:
If(cin)
While(cin>>word)
IO標準庫的條件狀態:
strm::iostate 由各個iostream 類定義,用於定義條件狀態
strm::badbit strm::iostate類型的值,用於指出被破壞的流
strm::failbit strm::iostate類型的值,用於指出失敗的IO操作
strm::eofbit strm::iostate類型的值,用於指出流已經到達檔案的結束符
s.eof() 如果設定了流s的eofbit值,該函數返回true
s.bad() 如果設定了流s的badbit值,該函數返回true
s.fail() 如果設定了流s的failbit值,該函數返回true
s.good() 如果流s處於有效狀態,該函數返回true
s.clear() 清空流s的所有狀態,並設為true
s.clear(flag) 給流s的某個條件狀態位設定為true。flag,類型是strm::iostate
s.setstate(flag)給流s的添加指定條件。flag,類型是strm::iostate
s.rdstate() 返迴流s的當前條件,傳回值類型是strm::iostate
流狀態的查詢和控制:
int ival;
while(cin>>ival,!cin.eof())//逗號操作符,首先計算它的每一個運算元,然後返回最右邊的運算元作為整個操作的結果。
{
if(cin.bad())
/*do something*/
if(cin.fail())
{ cerr<<”bad data”;
cin.clear(istrea::failbit);
continue;
}
}
輸出緩衝區的管理:
每個IO對象管理一個緩衝區,用於儲存程式讀寫的資料。
os<<”please”;
系統將字串字面值儲存在與流os相關的緩衝區中。下面幾種情況將導致緩衝區的內容被重新整理,即寫入到真實的輸出裝置或者檔案。
(1)程式正常結束,作為main的返回工作的一部分,將清空所有的輸出緩衝區。
(2)在一些不確定的時候,緩衝區可能已經滿了,此時,緩衝區將會在寫下一個值之前重新整理。
(3)用操縱符顯示的地重新整理,如endl,flush,ends.
(4)每次輸出操作執行完成後,用unitbuf操縱符設定流的內部狀態,從而清空緩衝區
(5)將輸出資料流與輸入資料流關聯(tie)起來,此時,在讀輸入資料流時將重新整理其關聯的輸出緩衝區。
檔案的輸入和輸出:
程式如果要讀寫控制視窗,那麼採用標準庫定義的對象cin,cout,cerr。
程式如果要讀寫檔案,需要自行定義對象,然後將它們綁定到問價上。
注意小心,如果需要重用檔案流讀寫多個檔案,那麼必須在讀另一個檔案之前調用clear()清除該流的狀態,然後再close()。否則,可能上個對象的錯誤狀態仍然殘留在新的對象那個那裡。
檔案模式:
in, out, app, ate, trunk, binary
字串流使用舉例:
String line, word;
While(getline(cin,line))
{
istringstream stream(line);
while(stream>>word)
{...}
}
檔案流概述
使用:檔案流對象>>變數1>>變數2>>…;完成讀操作;
使用:檔案流對象<<運算式1>>運算式2>>…;完成寫操作;
#include <iostream>
#include <fstream> //包含檔案流類標頭檔
int main()
{
ofstream out; //定義輸出資料流對象
out.open(“AAA”); //開啟檔案
if(!out) //檔案開啟失敗,out值為假
{
cout << "Cannot open AAA file./n";
return 1;
}
out << "C++ " << 89.5 << endl;
out << "English " << 93.5 << endl;
out << "Maths " << 87 << endl;
out.close(); //關閉檔案
}
類比理解檔案讀寫操作
就像cout是標準讀寫操作的輸出對象一樣,檔案讀寫操作中的輸出資料流對象是out.
就像標準讀寫操作的顯示目的地為顯示屏,檔案讀寫操作中的顯示目的地為檔案。
那麼,既然為檔案的話,肯定需要一行代碼區指明檔案名稱。那麼out和檔案名稱也就成了一套搭配工作的工具,一起把記憶體中的資料寫入檔案。
所以,一開始,需要定義ofstream的對象,也需要把這個具體的對象和一個具體的檔案關聯起來。