| 語言 | 頭文件 |
| C | <stdio.h> |
| C++ | <cstdio> |
參數均為字符數組 char[],不可直接傳遞 C++ std::string。
安全替代方案
// C11 安全版(可選實現)\
char *gets_s(char *str, rsize_t n);\
// 推薦:fgets 指定最大讀取長度\
char *fgets(char *str, int n, FILE *stream);\
// 讀取最多 n-1 字符,保留 \\n,遇 EOF/\\n 停止\
// C++ 最佳實踐\
#include \
#include \
std::string line;\
std::getline(std::cin, line); // 自動管理內存,無長度限制\
對比總結表
| 特性 | gets | fgets | std::getline |
| 緩衝區保護 | 無 | 有 (n) | 自動擴容 |
| 保留換行符 | 否 (轉\\0) | 是 | 否 (丟棄) |
| 標準狀態 | C11 移除 | C 標準 | C++ 標準 |
| 推薦程度 | ❌ 禁用 | ✅ C 環境首選 | ✅ C++ 環境首選 |
典型錯誤代碼與修正
// ❌ 錯誤:指針未分配內存\
char *cp;\
scanf("%s", cp); // 未初始化指針,野指針寫入\
// ✅ 修正 1:使用數組分配棧內存\
char cp[20];\
scanf("%19s", cp); // 限制寬度防溢出\
// ✅ 修正 2:動態分配\
char *cp = malloc(20);\
if (cp) { scanf("%19s", cp); free(cp); }\
// ✅ 修正 3:fgets 讀取整行含空格\
char line[100];\
fgets(line, sizeof(line), stdin);
最佳實踐建議
- 永不使用
gets,編譯器會警告,靜態分析工具會報錯。
- C 環境統一使用
fgets + 去除尾部 \\n 輔助函數。
- C++ 環境優先
std::getline + std::string。
scanf("%s") 同樣不安全,必須加寬度限制 %19s 或改用 fgets。
理解 gets 的危險性並掌握安全替代方案,是 C/C++ 開發者必備的安全編碼基礎素養。
- 上一篇文章: C語言 toascii 函數詳解:字符轉 ASCII 碼值完整示例
- 下一篇文章: C語言指針完全指南:從基礎概念到函數指針的系統性掌握
Copyright ©
程式碼之家 All Rights Reserved