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

C語言字符串排序:qsort + strcmp 實現字典序輸出

     編輯:C 語言問答

需求

輸入 n 個字符串,按字典序(ASCII 碼順序)從小到大輸出。

核心方案:標準庫 qsort

#include 
#include 
#include 

int cmp_str(const void *a, const void *b) {
    // qsort 傳入的是元素指針,此處元素為 char*,所以轉為 const char**
    const char * const *pa = (const char * const *)a;
    const char * const *pb = (const char * const *)b;
    return strcmp(*pa, *pb); // 利用 strcmp 比較字符串內容
}

int main() {
    int n;
    printf("請輸入字符串個數: ");
    if (scanf("%d", &n) != 1 || n <= 0) return 1;

    // 動態分配指針數組
    char **strs = malloc(n * sizeof(char *));
    if (!strs) return 1;

    // 讀取每行字符串(含空格)
    char buf[1024];
    getchar(); // 吞掉 scanf 留下的 \n
    for (int i = 0; i < n; i++) {
        if (!fgets(buf, sizeof(buf), stdin)) { n = i; break; }
        buf[strcspn(buf, "\n")] = '\0'; // 去掉換行符
        strs[i] = strdup(buf);          // 複製到堆內存
        if (!strs[i]) { perror("strdup"); return 1; }
    }

    qsort(strs, n, sizeof(char *), cmp_str);

    printf("\n排序結果:\n");
    for (int i = 0; i < n; i++) {
        puts(strs[i]);
        free(strs[i]); // 釋放字符串內存
    }
    free(strs);        // 釋放指針數組
    return 0;
}

關鍵技術點解析

點說明
qsort 原型void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void*, const void*));
比較函數接收 const void* 指向元素,**元素類型決定轉換方式**。此處元素是 char*,故轉 const char* const* 再解引用。
strcmp返回 <0/=0/>0 對應字典序 < / = / >,完美匹配 qsort 要求。
動態分配malloc 指針數組 + strdup(或 malloc+strcpy)每條字符串,長度不限、無浪費。
內存釋放**雙重 free**:先 free(strs[i]) 字符串,再 free(strs) 指針數組,順序不可反。
輸入處理fgets 讀整行支援空格,strcspn(buf,"\n") 安全去換行,避免 gets 漏洞。

進階:自定義比較規則

// 忽略大小寫排序
int cmp_icase(const void *a, const void *b) {
    return strcasecmp(*(const char**)a, *(const char**)b); // POSIX,Windows 用 _stricmp
}

// 按長度升序,長度相同按字典序
int cmp_len_lex(const void *a, const void *b) {
    const char *sa = *(const char**)a;
    const char *sb = *(const char**)b;
    size_t la = strlen(sa), lb = strlen(sb);
    if (la != lb) return (la > lb) - (la < lb); // 避免溢出的三元技巧
    return strcmp(sa, sb);
}

常見錯誤避坑

  1. ❌ cmp_str(const char *a, const char *b) 簽名錯誤 → qsort 傳的是元素地址,元素是指針,所以是二級指針。
  2. ❌ 直接排序二維數組 char strs[100][100] → qsort(strs, n, 100, cmp) 但 cmp 接收 char(*)[100],轉換麻煩且浪費空間,**指針數組更靈活**。
  3. ❌ 忘記 free → 內存洩漏。嚴格遵守「誰分配誰釋放」。
  4. ❌ scanf("%s") 讀字符串 → 遇空格截斷,改用 fgets。

總結

字符串排序 = 動態指針數組 + qsort + strcmp。
掌握 qsort 比較函數的**指針層級轉換**是關鍵:
元素類型 T → 比較函數參數 const void* → 轉 const T* → 解引用得 T → 比較。
此模式通用於任意類型數組排序(int、struct、double…)。

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