題目要求:輸入三個字元(無空格),按 ASCII 碼從小到大輸出,字元間以空格分隔。多組測試資料至 EOF。本文分析常見程式碼兩大錯誤:if 比較誤用單引號、scanf 遺留換行符導致讀取異常。
while (scanf("%c%c%c", &a[0], &a[1], &a[2]) != EOF) {
if ('a[0]' > 'a[1]') { ... } // ❌ 錯誤:單引號變成字元常數 'a'、'['、'0'、']' 比較
if ('a[0]' > 'a[2]') { ... }
if ('a[1]' > 'a[2]') { ... }
printf("%c %c %c\n", a[0], a[1], a[2]);
}
if (a[0] > a[1]) 直接比較變數值,而非字元常數。scanf("%c%c%c") 讀取三字元後,緩衝區仍殘留 \n。下一次迴圈 %c 會讀到此換行符。解法:在迴圈末尾加 getchar(); 或改用 scanf(" %c%c%c")(首個 %c 前加空白)跳過空白字元。#include <stdio.h>
int main() {
char a[3], t;
while (scanf("%c%c%c", &a[0], &a[1], &a[2]) == 3) { // 判斷讀取成功數量
getchar(); // 吞掉換行符,關鍵步驟
// 簡單選擇排序三元素
if (a[0] > a[1]) { t = a[0]; a[0] = a[1]; a[1] = t; }
if (a[0] > a[2]) { t = a[0]; a[0] = a[2]; a[2] = t; }
if (a[1] > a[2]) { t = a[1]; a[1] = a[2]; a[2] = t; }
printf("%c %c %c\n", a[0], a[1], a[2]);
}
return 0;
}
| 輸入 | 輸出 | 說明 |
|---|---|---|
| qwe | e q w | ASCII: e(101) q(113) w(119) |
| asd | a d s | a(97) d(100) s(115) |
| zxc | c x z | c(99) x(120) z(122) |
int cmp(const void *p1, const void *p2) {
return *(char*)p1 - *(char*)p2;
}
while (scanf("%c%c%c", &a[0], &a[1], &a[2]) == 3) {
getchar();
qsort(a, 3, sizeof(char), cmp);
printf("%c %c %c\n", a[0], a[1], a[2]);
}
'a[0]' 是多字元常數(實作定義行為),非變數存取 —— **嚴重邏輯錯誤**。%c 不跳過空白字元(含換行、空格),%d/%s 會跳過 —— **輸入處理核心差異**。scanf 返回值為成功轉換賦值的項目數,EOF 為負數,建議判斷 == n。修正兩大錯誤後,程式即能正確處理多組測試資料,輸出符合題目要求的排序結果。