char *gets(char *buf);
致命缺陷:不檢查緩衝區邊界。用戶輸入超過 buf 大小會導致緩衝區溢出,覆蓋相鄰內存,造成程序崩潰或安全漏洞。C11 標準已移除 gets。
char str[30];
gets(str); // 輸入 50 個 '1' → 緩衝區溢出 → 未定義行為
提供兩個重載版本的 Gets(大寫區分):
char *Gets(int maxlen) {
char *str = (char*)malloc(sizeof(char) * maxlen);
if (!str) {
perror("memory allocation error!");
return NULL;
}
int i = 0;
int c;
while (i < maxlen - 1 && (c = getchar()) != '\n' && c != EOF) {
str[i++] = c;
}
str[i] = '\0';
return str; // 調用者負責 free
}
// const 修飾指針本身不可修改,但可修改指向內容
// 類比:char str[30] 中 str 不可改,str[0] 可改
char *Gets(char *const array, int maxlen) {
int i = 0;
int c;
while (i < maxlen - 1 && (c = getchar()) != '\n' && c != EOF) {
array[i++] = c;
}
array[i] = '\0';
return array;
}
| 設計點 | 說明 |
|---|---|
參數 maxlen | 限制最大讀取字符數,預留 1 位給 \0 |
返回 char* | 鏈式調用便利,兼容原 gets 接口習慣 |
char *const | 防止傳入野指針導致崩潰;數組名退化為常量指針完美匹配 |
| 循環條件 | i < maxlen-1 確保不越界;檢查 EOF 處理文件結束 |
| 手動添加 \0 | 保證字符串正確終止 |
int main() {
// 固定數組版
char s[8];
Gets(s, 8);
puts(s);
fflush(stdin); // 清空輸入緩衝區,關鍵!
// 動態分配版
char *p = Gets(8);
puts(p);
free(p); // 必須釋放
return 0;
}
現代 C 開發應優先使用:
fgets(buf, size, stdin):標準、安全、保留換行符gets_s(buf, size):C11 Annex K,可選實現getline():POSIX,自動分配內存char *const 防指針篡改,const char* 防內容篡改free