我有这个代码,它将打印到控制台中给定文件夹中具有给定扩展名的所有文件:
int scandir(char dirname[], char const *ext)
/* Scans a directory and retrieves all files of given extension */
{
DIR *d = NULL;
struct dirent *dir = NULL;
d = opendir(dirname);
if (d)
{
while ((dir = readdir(d)) != NULL)
{
if (has_extension(dir->d_name, ext))
{
printf("%s\n", dir->d_name);
}
}
closedir(d);
}
return(0);
}
此函数有效,但我想修改它以便返回文件名数组。 (我已经做了很多谷歌搜索,但只提出像我这样的功能,打印到控制台)
我对C和'低级'相当陌生。编程,所以我不确定如何在这里正确处理内存。 当我不知道它有多大时,如何创建和添加字符数组?
我正在使用MinGW ..
答案 0 :(得分:2)
您可以使用realloc
:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
extern char *strdup(const char *src);
int scandir(char ***list, char dirname[], char const *ext)
/* Scans a directory and retrieves all files of given extension */
{
DIR *d = NULL;
struct dirent *dir = NULL;
size_t n = 0;
d = opendir(dirname);
if (d)
{
while ((dir = readdir(d)) != NULL)
{
if (has_extension(dir->d_name, ext))
{
*list = realloc(*list, sizeof(**list) * (n + 1));
(*list)[n++] = strdup(dir->d_name);
}
}
closedir(d);
}
return n;
}
int main(void)
{
char **list = NULL;
size_t i, n = scandir(&list, "/your/path", "jpg");
for (i = 0; i < n; i++) {
printf("%s\n", list[i]);
free(list[i]);
}
free(list);
return 0;
}
请注意,strdup()
不是标准函数,但在许多实现中都可用。
作为realloc
的替代方案,您可以使用singly linked list字符串。
编辑:正如@ 2501所指出的,最好从scandir
返回已分配的字符串数组,并将elems
作为参数传递:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
extern char *strdup(const char *src);
char **scandir(char dirname[], char const *ext, size_t *elems)
/* Scans a directory and retrieves all files of given extension */
{
DIR *d = NULL;
struct dirent *dir = NULL;
char **list = NULL;
d = opendir(dirname);
if (d)
{
while ((dir = readdir(d)) != NULL)
{
if (has_extension(dir->d_name, ext))
{
list = realloc(list, sizeof(*list) * (*elems + 1));
list[(*elems)++] = strdup(dir->d_name);
}
}
closedir(d);
}
return list;
}
int main(void)
{
size_t i, n = 0;
char **list = scandir("/your/path", "jpg", &n);
for (i = 0; i < n; i++) {
printf("%s\n", list[i]);
free(list[i]);
}
free(list);
return 0;
}
最后,你真的需要一个阵列吗?考虑使用回调函数:
#include <stdio.h>
#include <string.h>
#include <dirent.h>
void cb_scandir(const char *src)
{
/* do whatever you want with the passed dir */
printf("%s\n", src);
}
int scandir(char dirname[], char const *ext, void (*callback)(const char *))
/* Scans a directory and retrieves all files of given extension */
{
DIR *d = NULL;
struct dirent *dir = NULL;
size_t n = 0;
d = opendir(dirname);
if (d)
{
while ((dir = readdir(d)) != NULL)
{
if (has_extension(dir->d_name, ext))
{
callback(dir->d_name);
n++;
}
}
closedir(d);
}
return n;
}
int main(void)
{
scandir("/your/path", "jpg", cb_scandir);
return 0;
}