原始程式碼
char a[3] = {'0','0','0'};
scanf("%s", a);
for (int i=0; i<3; i++) printf("%c\n", a[i]);
現象
- 輸入
A → 輸出 A、亂碼、亂碼。
- 輸入
A00 → 正常輸出 A、0、0。
根本原因
scanf("%s", a) 讀取字串並自動在末尾附加 `\0`。
- 陣列大小僅 3,輸入
A 需 2 位元組('A' + '\0'),剛好放得下;但原始初始化 {'0','0','0'} 沒有 `\0`。
- 若輸入
A,寫入 a[0]='A', a[1]='\0',a[2] 保留舊值 '0'。迴圈印 3 個字元,第三個為殘留 '0'(非亂碼,但非預期)。
- 若輸入
AB(含 `\0` 需 3 位元組),緩衝區溢位,寫入 a[2]='\0' 之外的記憶體,行為未定義(真正亂碼/崩潰來源)。
修正方案
// 方案 1:陣列足夠大,且初始化為全 0(含結束符)
char a[100] = {0}; // 或 {'\0'}
scanf("%99s", a); // 限制寬度防溢位
// 方案 2:使用 C++ string(推薦)
#include
#include
std::string s;
std::cin >> s;
for (char c : s) std::cout << c << '\n';
關鍵知識點
- C 風格字串必須以 `\0` 結尾,標準庫函式(
printf, strlen, strcpy)皆依賴此約定。
%s 無長度限制極危險,務必用 %99s(陣列大小-1)。
- 現代 C++ 優先使用
std::string、std::getline、std::cin,避免手動記憶體管理。