Get names of files in a directory


#1

Does SDL2 provide a function to return a list of names of files in a specified directory? I know how I would do this with the Win32 API, and I am sure it can easily be done on Linux as well, but obviously I’d rather not have to create separate code for each platform if SDL has already done that.


#2

Not that I am aware of (I wish it did!). I have the same need as you, and I call opendir(), readdir() and closedir() in the C runtime. Fortunately this seems to work on all the platforms I support (Windows, Linux, MacOS, Android, iOS) so at least there is no need for a messy platform-specific solution.


#3

Interesting. I don’t seem to have access to the opendir family of functions on windows. What header files should I include? Perhaps it’s because I’m using Visual Studio.


#4

The header file is <dirent.h> I believe. I can’t comment on any possible VS factor since I’m using GCC.


#5

Doesn’t look like Visual Studio supports dirent.h, so I’m just gonna do the ugly platform-specific solution and live with it. Here’s my very inelegant implementation for Windows:

[ EDIT: Updated code to be less error-prone ]

// C99

#ifdef _WIN32
#include <windows.h>

// Returns an array of filenames in the directory specified by 'path', 
// or '0' if no files are found. 'size_return' is optional - the size_t that
// it points to is set to the size of the returned array.
char **directory_files(const char *path, size_t *size_return)
{
    size_t count = 0;
    char **filenames = 0;

    HANDLE hFind;
    WIN32_FIND_DATA data;

    // Count Files
    hFind = FindFirstFile(path, &data);
    if (hFind != INVALID_HANDLE_VALUE)
    {
        do 
        {
            ++count;
        } 
        while (FindNextFile(hFind, &data));

        FindClose(hFind);
    }

    if (count > 0)
    {
        filenames = malloc(sizeof(*filenames) * count);
        size_t i = 0;

        // Copy File Names to Array
        hFind = FindFirstFile(path, &data);
        if (hFind != INVALID_HANDLE_VALUE)
        {
            do 
            {
                filenames[i] = malloc(strlen(data.cFileName) + 1);
                strcpy(filenames[i], data.cFileName);
                ++i;
            } 
            while (FindNextFile(hFind, &data));

            FindClose(hFind);
        }
    }

    if (size_return) *size_return = count;

    return filenames;
}

void free_directory_files(char **filenames, size_t size)
{
    if (filenames)
    {
        for (size_t i = 0; i < size; ++i)
            free(filenames[i]);

        free(filenames);
    }
}

#endif // _WIN32