【问题标题】:scan directory program- compilation error扫描目录程序-编译错误
【发布时间】:2014-10-23 10:11:32
【问题描述】:

以下程序出现编译错误 试图扫描给定的目录并列出文件。

我尝试对malloc return value 进行类型转换,但仍然是同样的错误。谢谢。

错误

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]

【问题讨论】:

    标签: c linux pointers


    【解决方案1】:

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

    在你的情况下,例如这样:

    ent2 = (struct dirent *)malloc(len)
    

    其他问题

    scandir 的参数 4 int (*compar)(const struct dirent **, const struct dirent **)Aalphasort(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 中的演员表

    【讨论】:

    • 谢谢。我现在没有得到铸造错误。你能检查一下调用scandir()是否有问题,因为它现在失败了。 n = scandir("/etc", &namelist, NULL, Aalphasort);
    • 查看我修改后的答案。
    猜你喜欢
    • 2015-01-05
    • 1970-01-01
    • 2011-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多