使用stdlib的qsort()对字符串数组进行排序

时间:2011-03-20 19:08:23

标签: c arrays string segmentation-fault qsort

一些前言:我是一名计算机工程专业的学生,​​经过3个学期的Java(直到数据结构),在C语言中取得了第一堂课。这个问题与家庭作业有关,但为我解决了一些步骤。

我有一个输入文件,我读入内存,以便存储在char [9] [500]中。我读入最多500个最大长度为8的字符串。我试图使用stdlib内置的qsort()函数对此数组进行排序,并且存在一些内存错误。

重要的代码片段:

char data[4][500][60];
char debug[500][9];
size_t count = 0;

/* initialize file, open for reading */
FILE* pUserlog;
pUserlog = fopen("userlog","r");

while(!feof(pUserlog))
{
    fscanf(pUserlog, "%9s %8s %16s",debug[count], data[1][count], data[2][count]);
    fgets(data[3][count], 60, pUserlog);
    count++;
}

此部分将数据读入数组。这部分感兴趣的数组是“debug”。这是上面指定的数组。这是我对qsort的比较函数:

int compare(const void* a, const void* b)
{
    const char **ia = (const char **)a;
    const char **ib = (const char **)b;
    puts("I'm in compare!");
    return strncmp(*ia, *ib,8);
}

这是我尝试调用qsort:

size_t debug_len = sizeof(debug)/sizeof(char*);
printf("debug len: %d, count: %d, sizeof(char*): %d\n",debug_len,count,sizeof(char*));
qsort(debug,count, sizeof(char *), compare);

我试图在我的调用中替换debug_len,其中count是,但我仍然是segfaulting。这是输出:

$ ./test
debug len: 1125, count: 453, sizeof(char*): 4
I'm in compare!
Segmentation fault (core dumped)

谢谢!

2 个答案:

答案 0 :(得分:9)

compare函数将接收指向要比较的元素的指针。您正在尝试使用strncmp()比较字符。由于您有指向每个字符串的指针,因此将其强制转换为char *并进行比较。

int compare(const void* a, const void* b)
{
    const char *ia = (const char *)a;
    const char *ib = (const char *)b;
    puts("I'm in compare!");
    return strncmp(ia, ib, 9);
}

还要记住,它是一个数组数组,而不是一个指针数组。因此元素的大小应该是数组的大小9而不是指针4的大小。此时,使用sizeof debug[0]会更容易,因为它是一个二维数组。如果你没有使用正确的尺寸,qsort()只会破坏你的阵列。

size_t elemsize = sizeof debug[0];      /*   9 - size of each element */
size_t count = sizeof(debug)/elemsize;  /* 500 - number of elements in array */
qsort(debug, count, elemsize, compare);

答案 1 :(得分:4)

这里发生的是:你有500个字符串。现在你将所有500传递给qsort,然后它将每个传递给你的比较函数作为第一个和第二个参数。这有点像写这个:

compare(debug[0], debug[1])

C编译器传递地址,而不是实际值。但现在您将指向void的指针解释为指向指针的指针。您的代码现在在调用strncmp时会取消引用,但这会使(前4个字节)被视为strncmp中的指针。但是strncmp现在将依次尝试取消引用垃圾“指针”(它由你的一个字符串的一部分组成),这使得 bang

要解决此问题,请使用char *代替char **

int compare(const void* a, const void* b)
{
    puts("I'm in compare!");
    return strncmp((const char *)a, (const char *)b, 8);
}