原代碼 read_line(char str[], int n) 存在嚴重缺陷:當輸入字符超過 n 時,循環雖停止寫入,但 str[i] = '\0' 仍在固定大小棧數組內操作,若調用者傳入的數組小於實際輸入長度,會導致棧溢出、未定義行為。
int read_line(char str[], int n) {
int ch, i = 0;
while ((ch = getchar()) != '\n')
if (i < n) str[i++] = ch; // 超過 n 後不再寫入,但 ch 仍在讀取
str[i] = '\0'; // 危險:i 可能已等於 n,str[n] 越界
return i;
}
char* read_line_dynamic() {
size_t capacity = 128;
size_t len = 0;
char* buf = malloc(capacity);
if (!buf) return NULL;
int ch;
while ((ch = getchar()) != '\n' && ch != EOF) {
if (len + 1 >= capacity) { // 預留 \0 位置
capacity *= 2;
char* new_buf = realloc(buf, capacity);
if (!new_buf) { free(buf); return NULL; }
buf = new_buf;
}
buf[len++] = (char)ch;
}
buf[len] = '\0';
return buf; // 調用者負責 free
}
realloc。free() 釋放。EOF。NULL,調用者必須檢查。#include <string>
std::string read_line_cpp() {
std::string line;
std::getline(std::cin, line); // 自動處理內存、換行、EOF
return line;
}
結論:C 語言手寫動態行讀取極易出錯,工程上能用 C++ string 絕不手寫 char*,必須用 C 時嚴格遵循「誰分配誰釋放、檢查返回值、邊界檢查」三原則。