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

C 語言結構體數組排序常見錯誤修正:scanf 取址、struct 誤用、冒泡邏輯

     編輯:程式設計綜合問答

原始代碼核心錯誤

// 錯誤 1:scanf 取址語法錯誤
scanf("%s,%s,%4d,%5d,%5d\n", &sell[i]dm, &sell[i].mc, ...);  // &sell[i]dm 缺少 .

// 錯誤 2:if 條件中多寫 struct 關鍵字
if (struct(sell[i].mc > sell[i+1].mc))  // struct 這裡是類型關鍵字,不能用在表達式中

// 錯誤 3:結構體整體交換邏輯缺失
// 僅交換了 mc 和 je,其他字段 (dm, dj, sl) 未交換,導致數據錯位

// 錯誤 4:循環邊界與排序算法不完整
// 外層循環條件未給出,內層邏輯僅處理部分字段

修正後的完整可編譯代碼

#include 
#include 

#define MAX 100

typedef struct {
    char dm[5];      // 代碼,+1 存 \0
    char mc[11];     // 名稱
    int dj;          // 單價
    int sl;          // 數量
    long int je;     // 金額
} Sell;

Sell sell[MAX];

// 交換兩個結構體變量 (整體交換)
void SwapSell(Sell *a, Sell *b) {
    Sell tmp = *a;
    *a = *b;
    *b = tmp;
}

int main() {
    int n, i, j;
    
    printf("請輸入記錄數 (≤%d): ", MAX);
    if (scanf("%d", &n) != 1 || n <= 0 || n > MAX) return 1;
    getchar(); // 吸收換行
    
    // 輸入
    for (i = 0; i < n; i++) {
        printf("第 %d 筆 (代碼,名稱,單價,數量,金額): ", i+1);
        // 格式:代碼,名稱,單價,數量,金額
        // %4s 防止溢出 dm[5],%10s 防止溢出 mc[11]
        if (scanf("%4[^,],%10[^,],%d,%d,%ld", sell[i].dm, sell[i].mc, &sell[i].dj, &sell[i].sl, &sell[i].je) != 5) {
            fprintf(stderr, "輸入格式錯誤\n");
            return 1;
        }
        getchar(); // 吸收換行
    }
    
    // 冒泡排序:按名稱 mc 升序,名稱相同按金額 je 降序
    for (i = 0; i < n - 1; i++) {
        for (j = 0; j < n - 1 - i; j++) {
            int cmp = strcmp(sell[j].mc, sell[j+1].mc);
            if (cmp > 0 || (cmp == 0 && sell[j].je < sell[j+1].je)) {
                SwapSell(&sell[j], &sell[j+1]);
            }
        }
    }
    
    // 輸出
    printf("\n排序結果:\n");
    printf("%-6s %-12s %6s %6s %10s\n", "代碼", "名稱", "單價", "數量", "金額");
    for (i = 0; i < n; i++) {
        printf("%-6s %-12s %6d %6d %10ld\n", 
               sell[i].dm, sell[i].mc, sell[i].dj, sell[i].sl, sell[i].je);
    }
    return 0;
}

關鍵修正點解析

錯誤類別原寫法修正寫法說明
scanf 取址&sell[i]dmsell[i].dm (數組名即地址)字符數組名本身是地址,不需 &;非數組成員需 &
scanf 格式串%s,%s,%4d,%5d,%5d%4[^,],%10[^,],%d,%d,%ld掃描集合 [^,] 讀取逗號前內容,防止空格截斷;寬度限制防溢出
if 條件if (struct(sell[i].mc > sell[i+1].mc))if (strcmp(sell[j].mc, sell[j+1].mc) > 0)struct 是類型關鍵字;字符串比較必須用 strcmp
結構體交換逐字段交換 mc、jeSwapSell(&sell[j], &sell[j+1]) 整體交換結構體賦值複製所有成員,簡潔無遺漏
排序邏輯單層循環、條件不全標準冒泡雙層循環,複合條件 (名稱升、金額降)穩定、完整、易讀

進階優化建議

  1. 輸入健壯性:用 fgets 讀整行 → sscanf 解析,避免 scanf 留殘緩衝區導致後續讀取失敗。
  2. 動態內存:記錄數不固定時用 malloc/realloc 管理 Sell* 數組。
  3. qsort 庫函數:大數據量替換冒泡,編寫比較函數 int cmp(const void *a, const void *b)。
  4. 鍵盤輸入 vs 文件重定向:代碼同時支持 ./a.out < data.txt 和交互輸入。

總結

C 語言結構體數組排序,核心在於:scanf 格式串精確匹配輸入格式、字符串比較用 strcmp、結構體整體交換、排序邏輯完整覆蓋所有排序鍵。掌握這四點,同類作業輕松拿捏。

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