返回C中文件夹中的文件列表

时间:2014-10-14 09:52:56

标签: c pointers mingw dirent.h

我有这个代码,它将打印到控制台中给定文件夹中具有给定扩展名的所有文件:

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 ..

1 个答案:

答案 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;
}