struct - 使用qsort对c-string进行排序

时间:2009-11-27 02:46:15

标签: c sorting struct

我正在排序一堆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);
}

任何帮助都会很感激。感谢

3 个答案:

答案 0 :(得分:7)

你有一个指向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);
}

答案 1 :(得分:3)

您将IP地址排序为字符串。如果它们被标准化,这实际上会起作用:如果您希望这样做,则应该66.249.71.3而不是066.249.071.003

我认为最好的办法是使用一个将点分的IP地址转换为32位整数的函数,然后使用生成的整数作为排序键对它们进行排序。

您应该可以使用inet_addr()进行此转换。将其添加到您的程序中:

#include <arpa/inet.h>

文档here

答案 2 :(得分:2)

至少有两种修复排序代码的方法。一种是修改比较器函数以匹配对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'地址出现在其他数据之前,等等。修复需要一个更复杂的比较器 - 史蒂夫在他的回答中描述了一个解决方案