【发布时间】: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。