天天看點

IO庫

c++ 語言中不直接處理輸入和輸出,而是通過一族定義在标準庫中的類型來處理IO,這些類型支援從裝置讀取資料、向裝置寫入資料的IO操作。裝置可以是檔案、控制台視窗等。還有一些IO運作記憶體IO,即可以從string中讀寫資料。

IO庫

IO類

最開始接觸的c++ 中的io是我們從控制台接受輸入的istream和輸出到控制台中的ostream。除了基本的istream和ostream以外标準庫中還定義了如下的基本類型

iostream 用于讀寫流的基本類型

  1. istream、wistream: 從流讀取資料
  2. ostream、wostream: 向流寫入資料
  3. iostream、wiostream:從流中讀寫資料

fstream 定義了讀寫命名檔案的類型

  1. ifstream、wifstream: 從檔案中讀寫資料
  2. ofstream、wofstream: 向檔案中寫入資料
  3. fstream、wfstream: 讀寫檔案

sstream 定義了讀寫記憶體string對象的類型

  1. istringstream、iwstringstream: 從string中讀取資料
  2. ostringstream、owstringstream: 向string中寫入資料
  3. stringstream、wstringstream: 讀寫string

其中帶w的都是款位元組版本

無法對io對象進行拷貝或者指派、是以在函數中無法傳回IO類型也無法傳遞IO類型,隻能使用IO類型的引用

讀寫一個IO對象會改變其狀态,是以在函數中傳遞和傳回IO的對象不能是const的

一個流如果發生錯誤,其上後續的IO操作都會失敗。隻有當一個IO流處于無錯誤狀态時,我們才能從它讀取資料。是以代碼通常應該在使用一個流之前檢查它是否處于良好狀态,确定一個流對象的狀态最簡單的方式是将它作為一個條件來使用。

作為條件使用隻能告訴我們流是否有效,而無法告訴我們具體發生了什麼。IO庫定義了一組與機器無關的iostate類型,這個類型中使用二進制位來表示每種狀态。目前定義了4種錯誤類型:

  1. badbit: 流崩潰
  2. failbit: IO操作失敗
  3. eofbit: 流到達了檔案結束位置
  4. goodbit: 流未處于錯誤狀态

在實際使用時可以将具體值與這些預定義的值做位與運算,得到具體的原因

流對象的rstate 成員傳回目前流的狀态,setstate用來設定流狀态。clear不帶參用來清理所有錯誤标志位。clear的帶參版本接受一個iostate值,表示流的新狀态

io操作比較耗時,是以作業系統為了效率會提供緩沖機制。輸入輸出并不是立即執行的,作業系統提供了一個緩沖區,在适當的實際會使用緩沖區的資料,統一執行輸入輸出操作。導緻重新整理的原因有很多:

  1. 程式正常結束,在main函數執行return時,會進行重新整理操作
  2. 緩沖區滿時,會進行換新操作
  3. 程式中使用操作符例如endl來顯式的重新整理緩沖區
  4. 輸出操作結束後,使用操作符unitbuf 設定流的内部狀态來清空緩沖區,預設情況下cerr 是設定了unitbuf 的,是以cerr的内容都是實時重新整理的
  5. 一個輸出流被關聯到另一個輸出流。當讀寫被關聯到另一個流時,關聯到的流的緩沖區會被重新整理

除了使用endl、flush、ends 都可以來重新整理緩沖區。endl在重新整理的同時會插入換行符,flush則不添加任何字元,ends會添加一個空字元

如果想在每次輸出後都重新整理緩沖區,可以使用unitbuf 操作符,它告訴流,每次執行寫操作之後都進行一個flush操作

cout << unitbuf;
cout << nounitbuf;      

如果程式崩潰,緩沖區是不會被重新整理的

标準庫是将cin和cout關聯到一起了,是以每次執行cin都會導緻cout的緩沖區被重新整理

可以使用tie 方法将自身關聯到另一個流上。

tie 帶參數的版本,需要傳入一個指向ostream 的指針,将自己關聯到這個ostream中

tie 不帶參數的版本用來查詢自身關聯到了哪個輸出流上,傳回對應輸出流的指針,如果未被關聯,則傳回空指針

每個輸入流最多隻能關聯到一個輸出流,但是多個輸入流可以關聯到同一個ostream

檔案IO

當我們要讀寫一個檔案時可以使用檔案流對象

ifstream in(ifile); //傳入檔案名,構造一個ifstream 并打開檔案
ofstream out; //定義一個檔案輸出流,這個流不關聯到任何檔案      

當我們定義了空的檔案流對象後可以使用open函數将對象和檔案關聯起來。可以手動調用close函數關閉檔案。也可以在fstream對象被銷毀時由它的構造函數自動調用close

每個流都有一個關聯的檔案模式,用來指出該如何使用檔案

  1. in: 以讀的方式打開
  2. out: 以寫的方式打開
  3. app: 每次寫操作前均定位到檔案尾部
  4. ate: 每次打開檔案後立即定位到檔案尾部
  5. trunc: 截斷檔案
  6. binary:以二進制的形式打開檔案

string 流