題目要求:使用字元陣列(char[])儲存字串,不呼叫 strcat、strcpy 等庫函數,透過迴圈逐字元拷貝實現兩字串連接。以下提供標準、安全、含邊界檢查的完整實作。
a,記錄有效長度 lenA。b,記錄有效長度 lenB。lenA + lenB < 目標陣列容量,防止緩衝區溢位。b[0..lenB-1] 依序拷貝至 a[lenA..lenA+lenB-1]。'\0' 結束符。#include
#include // 僅用於 strlen 示範,實際可自行實現
constexpr int MAX_LEN = 500;
int main() {
char a[MAX_LEN] = {0};
char b[MAX_LEN] = {0};
std::cout << "請輸入字串 1: ";
std::cin.getline(a, MAX_LEN); // 讀取整行含空白
std::cout << "請輸入字串 2: ";
std::cin.getline(b, MAX_LEN);
// 1. 計算有效長度(不含結束符)
int lenA = 0;
while (lenA < MAX_LEN && a[lenA] != '\0') ++lenA;
int lenB = 0;
while (lenB < MAX_LEN && b[lenB] != '\0') ++lenB;
// 2. 邊界檢查
if (lenA + lenB >= MAX_LEN) {
std::cerr << "錯誤:連接後超過緩衝區容量 (" << MAX_LEN << ")\n";
return 1;
}
// 3. 手動拷貝:將 b 接到 a 尾部
for (int i = 0; i < lenB; ++i) {
a[lenA + i] = b[i];
}
// 4. 補上結束符
a[lenA + lenB] = '\0';
std::cout << "連接結果: " << a << '\n';
return 0;
}
| 細節 | 說明 |
|---|---|
cin.getline() vs cin >>> | getline 可讀取含空白的整行;>> 遇空白停止。 |
結束符 '\0' | C 風格字串以 '\0' 判斷結尾,拷貝後必須手動補上。 |
| 緩衝區溢位防護 | 連接前必須檢查 lenA + lenB < MAX_LEN,否則導致未定義行為。 |
不使用 strlen | 題目若嚴格禁止庫函數,可自寫 int myStrlen(const char* s) { int i=0; while(s[i]) ++i; return i; } |
// ❌ 錯誤 1:直接用 strcat(違反題目要求)
strcat(a, b);
// ❌ 錯誤 2:迴圈條件寫錯,導致漏拷貝或越界
for (int i = 0; i <= lenB; ++i) a[lenA + i] = b[i]; // 多拷貝了一個 '\0' 到中間
// ❌ 錯誤 3:未檢查容量,輸入超長直接崩潰
// ✅ 正確:如上方完整代碼所示
// 返回目標字串指針,失敗返回 nullptr
char* myStrcat(char* dest, int destCap, const char* src) {
int lenD = 0;
while (lenD < destCap && dest[lenD]) ++lenD;
int lenS = 0;
while (src[lenS]) ++lenS;
if (lenD + lenS >= destCap) return nullptr;
for (int i = 0; i < lenS; ++i) dest[lenD + i] = src[i];
dest[lenD + lenS] = '\0';
return dest;
}
掌握「先算長度、再查容量、後拷貝、最後補零」四步驟,即能在任何無庫函數限制的環境下安全完成字串連接。