我无法在C中对dirent结构进行排序。我已经尝试了所有内容,并且无法将我的struct数组的值显示在我的比较中。我的代码如下所示:
void printSortedNames(){
struct dirent **file_list = (dirent**)malloc(5 * sizeof(dirent*));
int i = 0;
for (i = 0; i < directory_size; ++i){
file_list[i] = (dirent*)malloc(50 * sizeof(dirent));
}
DIR *dir;
struct dirent *sd;
dir = opendir(".");
if (dir == NULL){
printf("Error! unable to open directory.\n");
exit(1);
}
int count = 0;
while ((sd = readdir(dir)) != NULL){
file_list[count] = sd;
printf("%s\n", file_list[count]->d_name);
++count;
}
size_t file_list_size = sizeof(&file_list) / sizeof(struct dirent);
qsort(file_list, file_list_size, sizeof(struct dirent), sizeCompare);
}
我创建了一个简单的函数sizeCompare来显示我的函数是否正常工作但我得到了null值。我的功能如下:
int sizeCompare(const void* a, const void* b){
printf("%s\n", ((const struct dirent*)a)->d_name);
}
有人可以向我解释为什么我的sizeCompare没有正确检索数组值吗?
更新 我试过玩qsort中的大小,结果我的值不再为null。以下行给出了一个输出:
qsort(file_list, 1000, sizeof(struct dirent), sizeCompare);
显然1000不是一个好的解决方案。有没有人知道像这样的数组的正确大小?
更新2: sizeCompare函数只接受第一个参数,第二个参数为null。
int sizeCompare(const void* a, const void* b){
const struct dirent *first_dirent = *(const struct dirent **) a;
const struct dirent *second_dirent = *(const struct dirent **) b;
.......
//first one works but second one is NULL
}
答案 0 :(得分:3)
您的sizeCompare
函数未返回任何内容。您需要实现的目的是在a < b
时返回-1,在a = b
时返回0,在a > b
时返回1。
int sizeCompare(const void* a, const void* b) {
// The implementation should return something
}
此外,您正在错误地计算file_list_size
。你不能将count
作为第二个参数传递吗?
qsort(file_list, count, sizeof(struct dirent), sizeCompare);
答案 1 :(得分:3)
在比较函数中,您需要通过首先转换为struct dirent **
来取消引用指针,就像这样
const struct dirent *first_dirent = *(const struct dirent **) first_parameter;
这是因为传递了每个元素的地址,因为元素是指针,所以传递给函数的指针是指向指针的指针。他们的void *
地址相同,但您无法将const struct dirent **
直接投放到const struct dirent *
。
你还有另一个重要问题,
file_list_size = sizeof(&file_list) / sizeof(struct dirent);
是错误的,尝试打印该值并查看它应该是 1
file_list_size = count;
因为你的代码计算指针的大小除以struct dirent
的大小,这可能导致0
,读取sizeof
运算符,它的结果取决于传递的参数。当它是变量时,类型的大小就是结果,当变量是数组时,它就是数组的大小。
由于file_list
是指向指针的指针,即不是数组,因此是
file_list_size = sizeof(&file_list) / sizeof(struct dirent);
不是您认为的或实际应该是什么。
没有正确的大小,也许您应该首先计算条目并预测代码中第一个malloc()
的值。或者使用realloc()
并动态计算条目并同时分配poitners。
此外:
您的代码在user3629249
您无需this comment
尽量不要将代码与声明混合,这样就很难跟踪变量及其范围。
您为5个struct dirent *
指针分配空间,但是您从不检查计数变量是否达到或超过该值。这可能导致未定义的行为。
您的代码也会泄漏内存,因为您从未致电closedir()
。
以下是按字母顺序对条目进行排序的示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
int
compareSize(const void *const A, const void *const B)
{
return strcmp((*(struct dirent **) A)->d_name, (*(struct dirent **) B)->d_name);
}
void printSortedNames(const char *const path)
{
int count;
DIR *dir;
struct dirent **list;
struct dirent *entry;
dir = opendir(path);
if (dir == NULL)
{
fprintf(stderr, "cannot open `%s'\n", path);
return;
}
/* First determine the number of entries */
count = 0;
while ((entry = readdir(dir)) != NULL)
++count;
/* Allocate enough space */
list = malloc(count * sizeof(*list));
if (list == NULL)
{
closedir(dir);
fprintf(stderr, "memory exhausted.\n");
return;
}
/* You don't need to allocate the list elements
* you can just store pointers to them in the
* pointer array `list'
*/
rewinddir(dir); /* reset position */
/* Save the pointers allocated by `opendir()' */
count = 0;
while ((entry = readdir(dir)) != NULL)
list[count++] = entry;
/* Call `qsort()', read about the `sizeof' operator */
qsort(list, count, sizeof(*list), compareSize);
/* Print the sorted entries now */
for (int index = 0 ; index < count ; ++index)
fprintf(stderr, "%s\n", list[index]->d_name);
closedir(dir);
}
int
main(void)
{
printSortedNames("/home/iharob");
return 0;
}
1 请记住将count
的值限制为为其分配空间的最大指针数。