我正在排序一堆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);
}
任何帮助都会很感激。感谢
答案 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'地址出现在其他数据之前,等等。修复需要一个更复杂的比较器 - 史蒂夫在他的回答中描述了一个解决方案