扫描目录程序 - 编译错误

时间:2014-10-23 10:11:32

标签: c linux pointers

我正在使用以下程序收到编译错误  试图扫描给定的目录和列表文件。

我尝试对malloc返回值进行类型转换,但仍然是同样的错误。感谢。

错误

sc.cpp: In function int scandir(const char*, dirent***, int (*)(const dirent*), int (*)(const dirent**, const dirent**)):
sc.cpp:35:58: error: invalid conversion from void* to dirent** [-fpermissive]
sc.cpp:46:24: error: invalid conversion from void* to dirent* [-fpermissive]
sc.cpp:51:70: error: invalid conversion from void* to dirent** [-fpermissive]
sc.cpp: In function int main(int, char**):
sc.cpp:85:50: error: invalid conversion from int (*)(const void*, const void*) to âint (*)(const dirent**, const dirent**) [-fpermissive]
sc.cpp:19:1: error:  initializing argument 4 of int scandir(const char*, dirent***, int(*)(const dirent*), int (*)(const dirent**, const dirent**)) [-fpermissive]

程序

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>

int Aalphasort(const void *_a, const void *_b)
{
    struct dirent **a = (struct dirent **)_a;
    struct dirent **b = (struct dirent **)_b;
    return strcoll((*a)->d_name, (*b)->d_name);
}


int
scandir(const char *dirname,
    struct dirent ***ret_namelist,
    int (*select)(const struct dirent *),
    int (*compar)(const struct dirent **, const struct dirent **))
{
    int i, len;
    int used, allocated;
    DIR *dir;
    struct dirent *ent, *ent2;
    struct dirent **namelist = NULL;

    if ((dir = opendir(dirname)) == NULL)
    return -1;

    used = 0;
    allocated = 2;
    //namelist = (struct dirent**) malloc(allocated * sizeof(struct dirent *));
    namelist =  malloc(allocated * sizeof(struct dirent *)); 
    if (!namelist)
    goto error;

    while ((ent = readdir(dir)) != NULL) {

    if (select != NULL && !select(ent))
        continue;

    /* duplicate struct direct for this entry */
    len = offsetof(struct dirent, d_name) + strlen(ent->d_name) + 1;
    if ((ent2 = malloc(len)) == NULL)
        return -1;

    if (used >= allocated) {
        allocated *= 2;
        namelist = realloc(namelist, allocated * sizeof(struct dirent *));
        if (!namelist)
        goto error;
    }
    memcpy(ent2, ent, len);
    namelist[used++] = ent2;
    }
    closedir(dir);

    if (compar)
    qsort(namelist, used, sizeof(struct dirent *),
          (int (*)(const void *, const void *)) compar);

    *ret_namelist = namelist;
    return used;


error:
    if (namelist) {
    for (i = 0; i < used; i++) 
        free(namelist[i]);
    free(namelist);
    }
    return -1;
}


int main(int argc, char **argv)
{
    struct dirent **namelist;
    int i, n;
    while(1)
    {
        n = scandir("/etc", &namelist, NULL, Aalphasort);
        for (i = 0; i < n; i++)
        {
            if( !strcmp(".",namelist[i]->d_name) || !strcmp("..",namelist[i]->d_name) )
            {
                printf("freeing for . and ..\n");
                free(namelist[i]);
            }
            else {
                printf("%s\n", namelist[i]->d_name); 
            free(namelist[i]);
            }
        }
        free(namelist);
        sleep(2);
    }
}

调用新错误:

 sc.cpp: In function int main(int, char**)
 sc.cpp:83:52: error: invalid conversion from âint (*)(const void*, const void*) to int (*)(const dirent**, const dirent**)â [-fpermissive]
 sc.cpp:17:5: error: initializing argument 4 of int Newscandir(const char*, dirent***, int (*)(const dirent*), int (*)(const dirent**, const dirent**)) [-fpermissive]

1 个答案:

答案 0 :(得分:0)

您实际上正在使用C ++编译器进行编译。 在C ++中,您必须将malloc的返回值转换为相应的类型。

在你的情况下,例如:

ent2 = (struct dirent *)malloc(len)

其他问题

int (*compar)(const struct dirent **, const struct dirent **)的参数4 scandirAalphasort(const void *_a, const void *_b)函数的签名不匹配。

变化:

int scandir(const char *dirname,
    struct dirent ***ret_namelist,
    int (*select)(const struct dirent *),
    int (*compar)(const struct dirent **, const struct dirent **))

为:

int scandir(const char *dirname,
    struct dirent ***ret_namelist,
    int (*select)(const struct dirent *),
    int (*compar)(const void *, const void *))

或更改:

int Aalphasort(const void *_a, const void *_b)
{
    struct dirent **a = (struct dirent **)_a;
    struct dirent **b = (struct dirent **)_b;
    return strcoll((*a)->d_name, (*b)->d_name);
}

为:

int Aalphasort(const struct dirent **a, const struct dirent **b)
{
    return strcoll((*a)->d_name, (*b)->d_name);
}

第二种解决方案更清晰,因为您避免使用Aalphasort

中的强制转换