char str[100];
gets(str); // 缺陷 1: gets 不檢查邊界,極易緩衝區溢出,C11 已移除
for (int i = 0; str[i] != '\0'; ) { // 缺陷 2: 循環體內無 i++,死循環
// 處理字符...
// 缺少 i++ 導致 i 永遠為 0,條件 str[0] != '\0' 永真 (除非空串)
}
| 問題 | 危害 | 修正方案 |
|---|---|---|
| 使用 `gets()` | 不限制輸入長度,超出數組邊界覆蓋棧內存 → 程序崩潰、任意代碼執行漏洞。C99 標記棄用,C11 正式移除。 | 用 `fgets(str, sizeof(str), stdin)`,自動讀取換行符,需手動去除尾部 `\n`。或 `scanf("%99s", str)` (不含空格)。 |
| for 循環缺少增量 | 循環變量 `i` 不變,條件永真 → **死循環**,CPU 100%,程序無響應。 | 在循環體末尾或 `for` 第三部分添加 `i++`: `for (int i = 0; str[i]; i++) { ... }` |
// 方案 1: fgets (推薦,保留空格、讀取整行)
char line[256];
if (fgets(line, sizeof(line), stdin)) {
line[strcspn(line, "\n")] = '\0'; // 移除尾部換行符
// 處理 line
}
// 方案 2: scanf 寬度限制 (不含空格)
char word[100];
if (scanf("%99s", word) == 1) { // %99s 限制最多讀 99 字符
// 處理 word
}
// 方案 3: 動態行讀取 (POSIX getline / C11 可選)
char *line = NULL;
size_t len = 0;
ssize_t read = getline(&line, &len, stdin);
if (read != -1) {
if (line[read-1] == '\n') line[read-1] = '\0';
// 處理 line
free(line);
}
// 模式 1: for 循環 (最常用)
for (int i = 0; str[i] != '\0'; i++) {
process(str[i]);
}
// 模式 2: while 循環 (指針算術)
char *p = str;
while (*p) {
process(*p++);
}
// 模式 3: 範圍 for (C++ 僅供參考)
for (char c : str) { // C++11
process(c);
}