【C++】輸入輸出

煮茶聽風雨發表於2022-02-03

一、緩衝

C++ 的輸入輸出均通過緩衝區來實現。緩衝區主要是為了解決速度不匹配的問題。

二、輸入(cin)

阻塞輸入。當輸入快取中無字元時則等待使用者輸入。

輸入緩衝

輸入緩衝是一種行緩衝。在輸入資料只要沒有碰到換行符(回車)就將資料存入輸入緩衝區,當碰到換行符之後就將緩衝區中的資料取出供變數使用,但是緩衝區中的換行符會被留在輸入緩衝區中。

cin>>

  • 讀取:從輸入快取中直接讀取(若輸入快取無有效字元,則要求使用者輸入)。
  • 不讀取快取首部的無效字元(空格、回車、換行)。
  • 結束條件:空格、回車、換行。
  • 其餘字元留在快取區中。

cin.get

a=cin.get() 或 cin.get(a)

  • 讀取:從輸入快取中直接讀取一個字元(若輸入快取無字元,則要求使用者輸入)。
  • 任意字元均可,包括無效字元(空格、回車、換行)。

cin.get(arrayname,size)

  • 讀取:從輸入快取中直接讀取(若輸入快取無字元,則要求使用者輸入)。
  • 若快取首部為空格、換行,則直接讀取。
  • $\star$ 若快取首部為換行符,則將 '\0' 賦給目標,設定失效位failbit,緩衝區被禁止讀取,回車留在緩衝區。
  • 結束條件:回車、到達size-1長度(最後一個字元存結束符)。
  • $\star$ 讀取結束後不會刪除快取區中的換行符。
  • $\star$ 超出size-1長度的字元留在緩衝區,供下一次讀取。
  • 只能將字串讀入C風格的字串中,即char*。

cin.get(arrayname,size,s)

s為結束符,cin.get(arrayname,size) 預設結束符為換行符。其餘用法和 cin.get(arrayname,size) 均一樣。

cin.getline

無讀取單個字元的形式

cin.getline(arrayname,size)

  • 讀取:從輸入快取中直接讀取(若輸入快取無字元,則要求使用者輸入)。
  • 若快取首部為空格、換行,則直接讀取。
  • $\star$ 若快取首部為換行符,則將 '\0' 賦給目標,將換行符刪除,結束此次讀取。
  • 結束條件:回車、到達size-1長度(最後一個字元存結束符)。
  • $\star$ 讀取結束後會刪除快取區中的換行符。
  • $\star$ 超出size-1長度,則設定失效位failbit,阻斷cin流,緩衝區被禁止讀取。
  • 只能將字串讀入C風格的字串中,即char*。

cin.getline(arrayname,size,s)

s為結束符,cin.getline(arrayname,size) 預設結束符為換行符。其餘用法和 cin.getline(arrayname,size) 均一樣。

getline(推薦!)

getline(cin, str)

  • cin.getline()屬於istream流,只能讀入char*型別中。而getline(cin, str)屬於string流,可以讀入string型別中。
  • cin與getline不能連用。因為cin會將 '\n' 留在緩衝區中,getline(cin, str) 遇到 '\n' 會直接返回。因此需要在cin>> 後加上cin.ignore()取出換行符。

cin.ignore

cin.ignore(size,s)

捨棄緩衝區中的長度為size或字元s之前的資料。

cin.ignore()

預設時size=1, s=EOF(檔案結束符)。常用來防止接收上次輸入的回車符。

cin.ignore(std::numeric_limits< streamsize >::max(), '\n')

其中,numeric_limits::max()是標頭檔案定義的流使用的最大值,也可以用一個足夠大的整數代替。

常用來清除輸入緩衝區的所有內容,使上次的輸入殘留下的資料不要影響到下一次的輸入。不要使用cin.sync(),sync()原意是同步輸入流,而不是清空緩衝區,在不同編譯器裡的實現可能不同,linux下g++就無法實現。

加'\n'為清除緩衝區中一行,但緩衝區中可能不止有一行。不加'\n'為清除EOF前所有的資料,但必須要確保緩衝區中有EOF符號,否則就會一直阻塞。

cin.clear

cin.clear() 將流cin中的所有狀態值都重設為有效狀態。

常用cin.clear() + cin.ignore(std::numeric_limits< streamsize >::max(), '\n') 清空緩衝資料。

三、輸出(cout、cerr、clog)

cout

標準輸出。有緩衝。

cout<<

表示輸出到緩衝區,並不是直接輸出到console。而是遇到endl和flush之類的才輸出。

endl、flush 和 \n

  • endl: 換行+重新整理輸出緩衝
  • \n: 換行
  • flush: 重新整理

由於輸出緩衝區為行緩衝,遇到換行符自動換行。因此 endl 和 \n 在使用上沒有什麼區別。若在 cout 後三者都不加,則不會輸出到console,直到後面程式重新整理緩衝區或程式結束。

cerr

沒有緩衝,傳送給它的內容立即被輸出。

clog

有緩衝。

相關文章