在上面的程序中,我使用malloc创建了一个指向char的指针数组,然后尝试使用qsort对这些“字符串”进行排序。我的结果不正确。更重要的是,每次运行程序时,我都会得到不同的结果。
#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;
}
我的猜测是我搞砸了我的strcmp等价物。我的比较出错的任何想法?
答案 0 :(得分:4)
问题是qsort
将指针传递给数组的元素。由于数组元素的类型为char *
,因此您的比较函数会收到 char **
输入。正如目前所写的那样,您将地址比作字符串,这自然会导致无意义的结果。
你应该写
const char *a = *(const char **)c;
const char *b = *(const char **)d;
ballin_compare
中的。
答案 1 :(得分:4)
char *a = (char *)c;
是双重错误。
首先,在C中,你不需要强制转换,如果没有必要,应该避免强制转换。
其次,您没有将实际字符串传递给比较器函数。你有指针(考虑一下:在实现qsort这样的通用排序函数时,不可能将任何类型的对象传递给比较器函数,因为要进行比较的对象可以是任何类型和大小)。所以你真正想要的是
const char *a = *(const char **)c;
还要注意const
的使用 - 这不是巧合。此外,只需使用
return strcmp(a, b);
你不需要(最好不要)重新发明轮子。
此外,read the funny manual - 所有这一切都在那里写得很清楚。