2

In the above program, I create an array of pointers to char using malloc and then attempt to sort those "strings" using qsort. I'm getting incorrect results. More importantly, I'm getting different results every time I run the program.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLINE 1000 
#define MAXCHARS 1000 
int ballin_compare(const void *, const void *); 

int main(int argc, char *argv[]){
    char *linebuffer, **pointbuffer; 
    FILE *fp;
        int i = 0;  

        if(argc < 2 || (fp = fopen(argv[1], "r")) == NULL)
            return 1; 

    linebuffer = (char *)malloc(MAXCHARS); 
    pointbuffer = (char **)malloc(sizeof(char *) * MAXLINE); 

    while(i < MAXLINE && fgets(linebuffer, MAXCHARS, fp) != NULL){
        pointbuffer[i] = (char *)malloc(strlen(linebuffer)); 
        strcpy(pointbuffer[i++], linebuffer); 
    }

    free(linebuffer); 
    qsort(pointbuffer, i, sizeof(char *), ballin_compare); 

    fclose(fp); 
    if((fp = fopen(argv[1], "w")) == NULL)
        return 1; 

    int x; 
    for(x = 0; x < i; x++)
        fputs(pointbuffer[x], fp);

    fclose(fp); 
    printf("%s sorted successfully", argv[1]);
        return 0;   
}



int ballin_compare(const void *c, const void *d){
    char *a = (char *)c; 
    char *b = (char *)d; 

    int i = 0;
    while(a[i] && b[i] && a[i] == b[i])
        i++; 

    if(a[i] < b[i])
       return -1; 
    if(a[i] > b[i])
       return 1; 

    return 0; 
}

My guess is that I messed up my strcmp equivalent. Any ideas where my comparisons went wrong?

4

2 回答 2

5

问题是qsort传递指向数组元素的指针。由于您的数组元素是 type char *,因此您的比较函数接收char **输入。正如目前所写的那样,您正在比较地址,就好像它们是字符串一样,这自然会导致无意义的结果。

你应该写

const char *a = *(const char **)c;
const char *b = *(const char **)d;

ballin_compare.

于 2013-08-10T01:28:18.650 回答
4
char *a = (char *)c;

是双重错误的。

首先,在 C 中,你不需要强制转换,如果不需要,应该避免强制转换。

其次,您没有将实际字符串传递给比较器函数。您有指向它们的指针(考虑一下:在实现诸如 qsort 之类的通用排序函数时,不可能将任何类型的对象传递给比较器函数,因为要比较的对象可以是任何类型和大小)。所以你真正想要的是

const char *a = *(const char **)c; 

还要注意使用const- 它的存在并非巧合。此外,只需使用

return strcmp(a, b);

你不需要(最好不要)重新发明轮子。

另外,阅读有趣的手册——所有这些都清楚地写在里面。

于 2013-08-10T01:29:29.177 回答