我正在使用Mac OS来实现命令排序功能的一部分: 我的部分代码如下:
int compare(const void *p, const void *q) {
return strcmp(*(char **)p, *(char **)q);
}
void sort_file(char *filename, int unique, int reverse) {
/* TODO: Complete this function */
/* Note: you will probably need to implement some other functions */
char buf[1024][1024];
int i=0;
FILE * fp;
if(!(fp=fopen(filename,"r"))){
perror("Open error!");
exit(0);
}
while(fgets(buf[i],1024,fp)){
printf("%s",buf[i]);
i++;
}
qsort(buf, i, sizeof(char *), compare);
}
结果始终显示segmentation fault: 11
任何人都可以告诉我这是什么问题以及如何修改它?
我仍然想知道,如果我不知道一行和文件中代码的最大大小,如何定义我的数组?
我从这个页面得到了这个想法: http://www.anyexample.com/programming/c/qsort__sorting_array_of_strings__integers_and_structs.xml
答案 0 :(得分:5)
你没有指针数组;你有一个数组数组。数组数组中的每个元素都有一个特定的固定步长为1024 char
。 qsort
需要知道这一点,而你却没有说出来。首先改变这个:
qsort(buf, i, sizeof(char *), compare);
到此:
qsort(buf, i, sizeof *buf, compare);
现在qsort
知道char数组数组中每个“东西”的大小。
接下来,应该更改比较器以考虑要传递的地址以及与数组数组相关的地址。传递给比较器的每个地址都是元素所在的位置。但是你的元素都是char[1024]
。某些char[1024]
的地址不是char**
,而是char(*)[1024]
。这里没有涉及指针的指针。你的比较器可以简单地是:
int compare(const void *p, const void *q)
{
const char (*lhs)[1024] = p;
const char (*rhs)[1024] = q;
return strcmp(*lhs, *rhs);
}
接下来,您的控制循环中没有限制器可以防止数组数组溢出。简而言之,这个:
while(fgets(buf[i],1024,fp))
应该是这样的:
while(i < 1024 && fgets(buf[i],1024,fp))
理想情况下,1024应该表示为某个常量,以避免幻数喷洒。
最后,你在函数中泄漏了一个开放的FILE*
。不是一个好的计划。确保fclose()
文件指针。
答案 1 :(得分:2)
我看到的问题:
错误的qsort
qsort(buf, i, sizeof(char *), compare);
需要:
qsort(buf, i, sizeof(buf[0]), compare);
由于buf+1
和buf
之间的差异为1000 char
s,因此使用sizeof(char*)
作为第三个参数是错误的。
compare
原始指针的类型为char (*)[1000]
,而不是char**
。因此,您需要使用:
int compare(const void *p, const void *q) {
char (*p1)[1000] = (char (*)[1000])(p);
char (*q1)[1000] = (char (*)[1000])(q);
return strcmp(*p1, *q1);
}