兩版 mcopy 函數複製字串,第一版輸出亂碼,第二版在迴圈結束後手動加上 `t[d] = '\0';` 即正常。為何會產生亂碼?
void mcopy(char *s, char *t, int m) {
int len = strlen(s);
for (int i = m-1, d = 0; i < len; i++, d++) {
t[d] = s[i];
}
// 缺少結束符
}
void mcopy(char *s, char *t, int m) {
int len = strlen(s);
for (int i = m-1, d = 0; i < len; i++, d++) {
t[d] = s[i];
}
t[d] = '\0'; // 關鍵補全
}
strlen(s) 回傳字串長度 不包含 結束符 `\0`。puts(t) 遇不到 `\0` 會繼續讀取記憶體直到隨機遇到 0,導致輸出亂碼。來源 s: 'H' 'e' 'l' 'l' 'o' '\0'
目的 t (複製前): 'X' 'X' 'X' 'X' 'X' 'X' 'X' ...
版本一複製後 t: 'H' 'e' 'l' 'l' 'o' 'X' 'X' ... ← 無結束符
版本二複製後 t: 'H' 'e' 'l' 'l' 'o' '\0' 'X' ... ← 正確結束
strncpy、snprintf 等自動處理結束符的函數。void safe_mcopy(const char *src, char *dst, size_t dst_size, int start_idx) {
if (!src || !dst || dst_size == 0) return;
size_t src_len = strlen(src);
if (start_idx < 0 || (size_t)start_idx >= src_len) { dst[0] = '\0'; return; }
size_t copy_len = src_len - start_idx;
if (copy_len >= dst_size) copy_len = dst_size - 1; // 留空間給 \0
memcpy(dst, src + start_idx, copy_len);
dst[copy_len] = '\0';
}
掌握「C 字串以 `\0` 結尾」這一核心規則,即可避免 90% 的字串處理亂碼問題。