首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ iostreams 標準輸入輸出詳解:cin/cout 緩衝機制、格式化提取與 getline 差異

     編輯:關於C++

cin/cout 是 istream/ostream 全域物件,綁定標準輸入輸出裝置。本文深入剖析其緩衝互動、格式化提取規則、get/getline 差異與 ignore 活用。

標準流與裝置關係

  • 標準輸入 (stdin):通常對應鍵盤,cin 讀取來源。
  • 標準輸出 (stdout):通常對應螢幕,cout 寫入目的地。
  • 標準錯誤 (stderr):cerr/clog,無緩衝/全緩衝區別。
  • Windows 控制台應用程式啟動時自動連接這三個標準裝置。

cin 提取運算子完整流程

  1. 檢查內部緩衝區:若 streambuf 有資料,直接格式化提取。
  2. 緩衝區空 → 觸發 I/O 等待:進程切換至等待狀態,OS 收集鍵盤輸入至系統緩衝區。
  3. 使用者輸入字元:字元回顯至螢幕(由終端機/Console Host 處理)。
  4. 按下 Enter:系統緩衝區包含完整行(含 \n)。
  5. 格式化提取:
    • 跳過前導空白(預設 skipws 旗標)
    • 根據目標型別解析(int 解析數字、string 讀至空白)
    • 將解析結果存入目標變數
    • 從 streambuf 移除已消耗字元(gptr 前進)

格式化提取分隔符差異

目標型別分隔符範例輸入提取結果殘留緩衝區
std::string空白、\t、\nhello world\n"hello"" world\n"
char[]空白、\t、\nhello world\n"hello\0"" world\n"
int非數字字元123abc\n123"abc\n"

完整行讀取:get() vs getline()

char buf[100];

// get():讀取至 \n,**保留 \n 於緩衝區**
cin.get(buf, 100);  // 讀 "hello world",緩衝區留 '\n'
cin.get(buf, 100);  // 立即讀到 \n → 空字串!

// getline():讀取至 \n,**擷取並丟棄 \n**
cin.getline(buf, 100);  // 讀 "hello world",緩衝區乾淨
cin.getline(buf, 100);  // 等待下一行輸入

解決方案:搭配 ignore()

cin.get(buf, 100);
cin.ignore();  // 跳過單一字元(預設 1, '\n')
cin.get(buf, 100);  // 正常讀取下一行

// 或一次跳過整行
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

cout 輸出機制

  • 每次 operator<< 完成後**自動 flush**(標準輸出通常行緩衝)。
  • 手動控制:cout << std::flush、cout << std::endl(換行+flush)、cout << '\n'(僅換行)。
  • cerr 無緩衝(unitbuf 旗標),立即輸出,適合錯誤訊息。
  • clog 全緩衝,適合日誌大量輸出。

同步與效能

// 關閉 C/C++ 標準流同步(加速純 C++ I/O)
std::ios::sync_with_stdio(false);
// 解除 cin/cout 綁定(進一步加速,但不可混用 printf/scanf)
cin.tie(nullptr);

競程/高效能 I/O 必開雙關閉。

常見陷阱

  1. cin >> str 後緩衝區留 \n,後續 getline 讀到空行 → 必須 cin.ignore()。
  2. 輸入型別不符設定 failbit,需 clear() + ignore() 恢復。
  3. 寬字元版 wcin/wcout 需配合 std::locale 設定正確編碼。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved