【问题标题】:C — Directory explorationC - 目录探索
【发布时间】:2014-11-07 13:05:07
【问题描述】:

我想用指定目录路径内的文件名和目录名动态填充字符串数组。

根据您的说法,这是为此目的最快的实现方式吗?

如果没有,您能否提出替代实施方案?

int exploreDirectory(const char *dirpath, char ***list, int *numItems) {
    DIR *dirstream = NULL;
    struct dirent *direntp = NULL;  
    size_t listSize = 5;

    errno = 0;
    if (!(dirstream = opendir(dirpath))) 
        return errno;       

    if (!((*list) = malloc(sizeof(char *) * listSize))) {
        fprintf(stderr, "Error in list allocation for file list: dirpath=%s.\n", dirpath);
        exit(EXIT_FAILURE);
    }

    *numItems = 0;

    while(1) {
        errno = 0;
        if (!(direntp = readdir(dirstream)))
            break;
        if (*numItems + 1 == listSize) {
            listSize *= 2;          
            if (!((*list) = realloc((*list), sizeof(char *) * listSize))) {
                fprintf(stderr, "Error in list reallocation for file list: dirpath=%s.\n", dirpath);
                exit(EXIT_FAILURE);
            }
        }
        *numItems += 1;     
        (*list)[*numItems - 1] = stringDuplication(direntp->d_name);    
    }

    if (errno != 0) {
        fprintf(stderr, "Error in readdir for file list: dirpath=%s.\n", dirpath);
        exit(EXIT_FAILURE);
    }

    if (closedir(dirstream) == -1) {
        fprintf(stderr, "Error in closedir for file list: dirpath=%s.\n", dirpath);
        exit(EXIT_FAILURE);
    }

    free(direntp);

    return 0;
}

【问题讨论】:

  • ftw() 和 nftw() 用于执行文件树遍历,降序目录。 find 命令基于 nftw()。 scandir() 读取一个目录的内容。我不完全确定其中哪一个满足您的需求,但它们可以非常有效地完成您已经编写的代码。
  • 感谢您对scandir的建议! ;-) 更改实现:现在基于 scandir!
  • 成语pointer = realloc(pointer, size) 是等待发生的内存泄漏。如果realloc() 失败,它会取消对先前分配的内存的引用。使用char **newlist = realloc((*list), sizeof(*list) * listSize); 并在分配给*list 之前检查newlist != 0
  • 我也认为free(direntp); 是一个麻烦的秘诀; closedir() 应该处理该内存。如有疑问请咨询valgrind

标签: c arrays directory


【解决方案1】:

这是基于scandir的实现!

int exploreDirectory(const char *dirpath, char ***list, int *numItems) {
    struct dirent **direntList;
    int i;
    errno = 0;

    if ((*numItems = scandir(dirpath, &direntList, NULL, alphasort)) == -1)
        return errno;

    if (!((*list) = malloc(sizeof(char *) * (*numItems)))) {
        fprintf(stderr, "Error in list allocation for file list: dirpath=%s.\n", dirpath);
        exit(EXIT_FAILURE);
    }

    for (i = 0; i < *numItems; i++) {
        (*list)[i] = stringDuplication(direntList[i]->d_name);
    }

    for (i = 0; i < *numItems; i++) {
        free(direntList[i]);
    }

    free(direntList);

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    • 1970-01-01
    • 2012-09-20
    • 2020-04-04
    • 1970-01-01
    • 1970-01-01
    • 2010-12-27
    相关资源
    最近更新 更多