簡體   English   中英

struct - 使用qsort對c-string進行排序

[英]struct - sorting a c-string with qsort

我正在排序一堆IP,但由於某種原因,它們的順序錯誤。 我不太確定問題出在哪里。

66.249.71.3      
190.148.164.245  
207.46.232.182   
190.148.164.245  
190.148.164.245  
202.154.114.253
190.148.164.245  
190.148.164.245  
66.249.71.3      
190.148.164.245  
202.154.114.253

這是我對它們進行排序的方式。

typedef struct {
    char *ip;
} mystruct;

/* qsort */
int struct_cmp(const void *a, const void *b)
{
    mystruct *ia = (mystruct *)a;
    mystruct *ib = (mystruct *)b;
    return strcmp(ia->ip, ib->ip);
} 
...
qsort(a_struct, 11, sizeof(mystruct*), struct_cmp);
for(..){
    printf("%s\n",a_struct[i]->ip);
}

任何幫助將是欣賞它。 謝謝

你有一個指向mystruct的指針數組,但是使用這個比較函數的qsort會期望一個簡單的mystruct數組。 要對mystruct*數組進行排序,需要在比較函數中添加另一級別的間接:

int struct_cmp(const void *a, const void *b) {
    mystruct *ia = *(mystruct **)a;
    mystruct *ib = *(mystruct **)b;
    return strcmp(ia->ip, ib->ip);
}

您將IP地址排序為字符串。 如果它們被標准化,這實際上會起作用:如果你想要它可以工作,你應該有066.249.071.003而不是66.249.71.3

我認為最好的辦法是使用一個將虛線IP地址轉換為32位整數的函數,然后使用生成的整數作為排序鍵對它們進行排序。

您應該能夠使用inet_addr()來執行此轉換。 將此添加到您的程序:

#include <arpa/inet.h>

文檔在這里

至少有兩種修復排序代碼的方法。 一種是修改比較器函數以匹配對qsort()的調用; 另一種方法是修復對qsort()的調用以匹配比較器。 正確的修復取決於數組的定義 - 但最簡單的聲明是結構數組(不是結構指針)。 因此,這個工作代碼 - 使用原始比較器但對qsort()的不同調用:

#include <stdlib.h>
#include <stdio.h>

typedef struct {
    char *ip;
} mystruct;

static mystruct a_struct[] =
{
    "66.249.71.3",
    "190.148.164.245",
    "207.46.232.182",
    "190.148.164.245",
    "190.148.164.245",
    "202.154.114.253",
    "190.148.164.245",
    "190.148.164.245",
    "66.249.71.3",
    "190.148.164.245",
    "202.154.114.253",
};

/* qsort */
static int struct_cmp(const void *a, const void *b)
{
    mystruct *ia = (mystruct *)a;
    mystruct *ib = (mystruct *)b;
    return strcmp(ia->ip, ib->ip);
}

static void print_list(mystruct *list, int n)
{
    int i;
    for (i = 0; i < n; i++)
        printf("%2d: %s\n", i, list[i].ip);
}

#define DIM(x)  (sizeof(x)/sizeof(*(x)))

int main(void)
{
    print_list(a_struct, DIM(a_struct));
    qsort(a_struct, DIM(a_struct), sizeof(mystruct), struct_cmp);
    print_list(a_struct, DIM(a_struct));
}

這只是給我們留下了一個字母數字排序的數組,所有'190.xyz'地址出現在其他數據之前,等等。修復需要更復雜的比較器 - 史蒂夫在他的回答中描述了一個解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM