Рекурсивный обход каталога. Какие библиотеки и функции использовать?

Нужно написать функцию обхода каталога, вместе с подкаталогами. Скорее всего должен использоваться рекурсивный подход. Проблема состоит в том, что в стандартной библиотеке ANSI C нет таких функций. Поиском удалось узнать, что в C POSIX есть заголовочный файл dirent.h который описывает необходимые функции, но они вроде как только под UNIX-подобные ОС. В среде разработки VIsual Studio данный заголовочный файл отсутствует. Но там вроде как есть функции findfirstfile( ), findnextfile( ), - которые обладают аналогичным функционалом.
Это учебная задача, не для "продакшена" - так что нужно сделать хоть как-нибудь, лишь бы работало. Программа должна демонстрировать работу в консольном режиме. В задаче не сказано под какую ОС должно быть приложение. Я думаю, что если возможно то должно универсальным, а если нет то без разницы.
  • Вопрос задан
  • 3097 просмотров
Пригласить эксперта
Ответы на вопрос 2
@Coderast
Универсально вряд ли возможно, так как Си не содержит CRT функций для поиска файлов.

Если винда, то FindFirstFileA и FindNextFileA из windows.h

https://msdn.microsoft.com/ru-ru/library/windows/d...
https://msdn.microsoft.com/ru-ru/library/windows/d...

typedef void (*LPSEARCHFUNC)(LPCTSTR lpszFileName);

BOOL SearchFiles(LPCTSTR lpszFileName, LPSEARCHFUNC lpSearchFunc, BOOL bInnerFolders = TRUE)
{
    LPTSTR part;
    char tmp[MAX_PATH]; 
    char name[MAX_PATH];

    HANDLE hSearch = NULL;
    WIN32_FIND_DATA wfd;
    memset(&wfd, 0, sizeof(WIN32_FIND_DATA));

    
    if(bInnerFolders)
    {
        if(GetFullPathName(lpszFileName, MAX_PATH, tmp, &part) == 0) return FALSE;
        lstrcpy(name, part);
        lstrcpy(part, "*.*");

        
        wfd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
        if (!((hSearch = FindFirstFile(tmp, &wfd)) == INVALID_HANDLE_VALUE))
        do
        {
            if (!strncmp(wfd.cFileName, ".", 1) || !strncmp(wfd.cFileName, "..", 2))            
            continue;
        
            if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                char next[MAX_PATH];
                if(GetFullPathName(lpszFileName, MAX_PATH, next, &part) == 0) return FALSE;
                lstrcpy(part, wfd.cFileName);
                lstrcat(next, "\\");
                lstrcat(next, name);

                SearchFiles(next, lpSearchFunc, TRUE);
            }
        }
        while (FindNextFile(hSearch, &wfd));

        FindClose (hSearch); 
    }

    if ((hSearch = FindFirstFile(lpszFileName, &wfd)) == INVALID_HANDLE_VALUE) 
        return TRUE;
    do
    if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 
    {
        char file[MAX_PATH];
        if(GetFullPathName(lpszFileName, MAX_PATH, file, &part) == 0) return FALSE;
        lstrcpy(part, wfd.cFileName);

        lpSearchFunc(file);
    }
    while (FindNextFile(hSearch, &wfd));
    FindClose (hSearch); 

    return TRUE;
}


Как находит файл по маске, вызывает функцию по указателю с прототипом:
void FileFound(LPCTSTR lpszFileName)
Ответ написан
@kazhuravlev
Не знаю как в C, но в некоторых языках есть функция walk(), которая возвращает список диреторий и поддиректорий в указанной директории golang.org/pkg/path/filepath/#Walk
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы