字符串輸入是 C 語言基礎但易錯的知識點。本文深度對比 gets() 與 scanf() 的行為差異,並通過實例說明緩衝區處理機制。
| 特性 | scanf("%s", str) | gets(str) |
|---|---|---|
| 空格處理 | 遇空格/Tab/換行停止 | 可接收空格/Tab |
| 換行符處理 | 留在緩衝區 | 讀取並替換為 \0 |
| 緩衝區殘留 | 分隔符留存 | 換行符不留存 |
| 安全性 | 需指定寬度防溢出 | 無長度檢查,極不安全 |
// 輸入: asd fg[回車]
char ch1[10], ch2[10];
scanf("%s", ch1); // ch1 = "asd\0"
gets(ch2); // ch2 = "asd fg\0"
\0\0scanf("%s", ch1); // 輸入 asdfg[回車]
c1 = getchar(); // c1 獲得殘留的 '\n'
gets(ch2); // 立即讀取空行(遇到殘留換行符)
解決方案:scanf 後用 getchar() 吞噬殘留換行符,或統一使用 fgets()。
棄用 gets() (C11 標準已移除),改用 fgets(str, size, stdin):
理解輸入函數的緩衝區語義,是避免 C 語言輸入處理 Bug 的關鍵。