void stringchang(const char* input, char* output) {
for (int i = 0; i < 255; i++) {
output[i] = input[i] + 1; // 1. 未檢查結束符,越界讀寫
switch (input[i]) {
case 'z': output[i] = 'a'; break;
case 'Z': output[i] = 'A'; break;
}
if (input[i] == '\0') break; // 2. 判斷在賦值後,已寫入垃圾數據
}
}
亂碼根因:
output[i] = input[i] + 1,再判斷 input[i] == '\0',導致結束符後的內存被寫入非 0 值,puts(output) 繼續打印直到遇到隨機 0。output 陣列未初始化,殘留棧上垃圾數據。+1,不符合「僅字母移位」需求。#include <stdio.h>
#include <string.h>
#include <ctype.h>
void stringchang(const char* input, char* output) {
int i = 0;
while (input[i] != '\0' && i < 254) { // 安全邊界
char c = input[i];
if (isalpha(c)) { // 僅處理字母
if (c == 'z') output[i] = 'a';
else if (c == 'Z') output[i] = 'A';
else output[i] = c + 1;
} else {
output[i] = c; // 非字母原樣複製
}
i++;
}
output[i] = '\0'; // 顯式添加結束符
}
int main() {
char input[255] = {0};
char output[255] = {0}; // 初始化為 0
fgets(input, sizeof(input), stdin); // 安全輸入,替代危險的 gets
input[strcspn(input, "\n")] = '\0'; // 移除換行符
stringchang(input, output);
puts(output);
return 0;
}
| 問題 | 修正 |
|---|---|
| 循環邊界硬編碼 | while (input[i] != '\0' && i < MAX-1) |
| 結束符判斷滯後 | 循環條件前置判斷,體內不再需判斷 |
| 輸出緩衝區未初始化 | char output[255] = {0}; |
| 非字母誤處理 | isalpha() 守衛 |
| 危險的 gets() | fgets() + 去換行 |
| 缺少顯式結束符 | 循環結束後 output[i] = '\0'; |
void stringchang_inplace(char* str) {
for (int i = 0; str[i]; i++) {
char c = str[i];
if (isalpha(c)) {
str[i] = (c == 'z') ? 'a' : (c == 'Z') ? 'A' : c + 1;
}
}
}
掌握緩衝區邊界控制、結束符管理、安全輸入函數,是 C 字符串處理無 Bug 的基石。