scanf 還是 cin?C/C++ I/O 機制徹底釐清scanf(格式化)、getchar/fgetc(字元)、fgets/gets(行,gets 已棄用)、fread(二進位塊)。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),否則未定義行為。%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 可關閉。std::ios::sync_with_stdio(true)),可呼叫 std::ios::sync_with_stdio(false); std::cin.tie(nullptr); 大幅提速,接近 scanf。if (cin >> n) 隱性轉換為 bool,失敗時設 failbit,需 cin.clear() 重置才能繼續讀取。| 方法 | 典型耗時 | 備註 |
|---|---|---|
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 秒 | 大塊讀取+自寫解析器最快 |
scanf/fgets/fread,搭配 errno、feof/ferror 做錯誤處理。ios::sync_with_stdio(false); cin.tie(nullptr); 後用 cin/cout。cin/cout,享受型別安全、可擴充性(自訂型別支援 operator>>)。printf 實作(vsnprintf + 發送緩衝區)。總結: C 用 scanf,C++ 推薦 cin(關閉同步後效能相當)。理解兩者緩衝、空白處理、錯誤狀態差異,能避免 90% 的輸入 Bug。