繁体   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