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

C 語言輸入用 scanf 還是 cin?C/C++ I/O 機制徹底釐清

     編輯:C 語言問答

核心結論

  • C 語言: 標準輸入函式為 scanf(格式化)、getchar/fgetc(字元)、fgets/gets(行,gets 已棄用)、fread(二進位塊)。
  • C++: 可用 C 風格 scanf,也可用 **iostream 庫** 的 std::cin(operator>>)、std::getline、std::istream::read。

scanf 詳細機制

int scanf(const char *format, ...);
// 從 stdin 讀取,按 format 解析,結果存入後續引數指向的位址
// 回傳成功匹配與賦值的項目數,EOF 表示輸入失敗/結束
  • 格式字串: %d (int), %f (float), %lf (double), %c (char), %s (字串, 遇空白停止), %[...] (掃描集合)。
  • 地址傳遞: 必須傳變數位址(&var),否則未定義行為。
  • 空白處理: 格式字串中的空白字元(空格、換行、Tab)會**跳過輸入流中任意數量的空白字元**;%c 不跳過空白,需用 " %c" 強制跳過。
  • 緩衝區殘留: scanf("%d", &n) 讀完數字後,換行符留在 stdin,後續 scanf("%c", &c) 會直接讀到換行符。解決:scanf(" %c", &c) 或呼叫 getchar() 吞掉換行。

std::cin (C++ iostream) 特性

std::cin >> n;          // 類型安全,自動根據 n 型別解析
std::cin.get(ch);       // 讀單一字元(含空白/換行)
std::getline(cin, str); // 讀整行(含空白),遇 '\n' 停止並丟棄換行
  • 型別安全: 編譯期根據右運算元型別選擇多載 operator>>,無格式字串錯誤風險。
  • 自動跳過空白: operator>> 預設啟用 std::skipws,讀數值/字串前自動吃掉空白;std::noskipws 可關閉。
  • 同步與效能: 預設與 C stdio 同步(std::ios::sync_with_stdio(true)),可呼叫 std::ios::sync_with_stdio(false); std::cin.tie(nullptr); 大幅提速,接近 scanf。
  • 狀態檢查: if (cin >> n) 隱性轉換為 bool,失敗時設 failbit,需 cin.clear() 重置才能繼續讀取。

效能對比(讀取 107 個整數)

方法典型耗時備註
scanf("%d", &x)~0.8-1.2 秒C 標準,無額外開銷
cin >> x (sync_on)~3-5 秒預設同步,執行緒安全但慢
cin >> x (sync_off + tie_off)~0.9-1.3 秒關閉同步後接近 scanf
fread + 手工解析~0.3-0.5 秒大塊讀取+自寫解析器最快

選擇建議

  1. 純 C 專案: 僅用 scanf/fgets/fread,搭配 errno、feof/ferror 做錯誤處理。
  2. C++ 專案:
    • 競程/高效能 I/O:ios::sync_with_stdio(false); cin.tie(nullptr); 後用 cin/cout。
    • 一般應用:直接用 cin/cout,享受型別安全、可擴充性(自訂型別支援 operator>>)。
    • 需混用 C 庫:小心同步問題,建議全專案統一風格。
  3. 嵌入式/裸機: 通常無標準庫,直接操作 UART/DMA 暫存器或用輕量 printf 實作(vsnprintf + 發送緩衝區)。

總結: C 用 scanf,C++ 推薦 cin(關閉同步後效能相當)。理解兩者緩衝、空白處理、錯誤狀態差異,能避免 90% 的輸入 Bug。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved