首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 語言 ASCII 排序:三字元輸入按碼值輸出,scanf 緩衝區換行符陷阱解析

     編輯:程式設計綜合問答

題目要求:輸入三個字元(無空格),按 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]);
}

兩大關鍵修正

  1. 移除比較式中的單引號:if (a[0] > a[1]) 直接比較變數值,而非字元常數。
  2. 消耗換行符: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;
}

測試驗證

輸入輸出說明
qwee q wASCII: e(101) q(113) w(119)
asda d sa(97) d(100) s(115)
zxcc x zc(99) x(120) z(122)

進階寫法:qsort 通用排序

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。

修正兩大錯誤後,程式即能正確處理多組測試資料,輸出符合題目要求的排序結果。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved