8

Как получить список файлов в директории с помощью C или C++?

1

Заголовок: Как получить список файлов в директории из кода на C или C++?

Текст вопроса: Я пытаюсь определить список файлов в директории из моего кода на C или C++, но не могу выполнить команду ls и обработать результаты. Есть ли какой-то способ сделать это, используя только стандартные библиотеки или доступные функции языка? Необходимо найти решение, которое будет работать на разных платформах, если это возможно. Спасибо!

5 ответ(ов)

1

Вы можете использовать следующий код для получения всех имен файлов в указанной папке, не прибегая к сторонним библиотекам (для Windows):

#include <Windows.h>
#include <vector>
#include <string>

using namespace std;

vector<string> get_all_files_names_within_folder(string folder)
{
    vector<string> names;
    string search_path = folder + "/*.*";
    WIN32_FIND_DATA fd; 
    HANDLE hFind = ::FindFirstFile(search_path.c_str(), &fd); 
    if(hFind != INVALID_HANDLE_VALUE) { 
        do { 
            // Считываем все (реальные) файлы в текущей папке
            // Исключаем записи для папок "." и ".."
            if(!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
                names.push_back(fd.cFileName);
            }
        } while(::FindNextFile(hFind, &fd)); 
        ::FindClose(hFind); 
    } 
    return names;
}

Вы можете изменить *.* на *.ext, чтобы получить только файлы определенного типа (например, .txt, .jpg и т.д.) в данной директории, как уже упомянул @Sebastian.

0

Для решения, использующего только C, обратите внимание на этот проект. Он требует лишь подключения одного дополнительного заголовка:

https://github.com/cxong/tinydir

Пример использования:

tinydir_dir dir;
tinydir_open(&dir, "/path/to/dir");

while (dir.has_next)
{
    tinydir_file file;
    tinydir_readfile(&dir, &file);

    printf("%s", file.name);
    if (file.is_dir)
    {
        printf("/");
    }
    printf("\n");

    tinydir_next(&dir);
}

tinydir_close(&dir);

Некоторые преимущества по сравнению с другими вариантами:

  • Портативность — обрабатывает POSIX dirent и Windows FindFirstFile.
  • Использует readdir_r, где это возможно, что делает его (обычно) потокобезопасным.
  • Поддерживает Windows UTF-16 через те же макросы UNICODE.
  • Совместимость с C90, что позволяет использовать его даже с очень старыми компиляторами.
0

Я рекомендую использовать glob с этим многоразовым обёрткой. Она генерирует vector<string>, который соответствует путям файлов, подходящим под шаблон glob:

#include <glob.h>
#include <vector>
using std::vector;

vector<string> globVector(const string& pattern){
    glob_t glob_result;
    glob(pattern.c_str(), GLOB_TILDE, NULL, &glob_result);
    vector<string> files;
    for(unsigned int i = 0; i < glob_result.gl_pathc; ++i){
        files.push_back(string(glob_result.gl_pathv[i]));
    }
    globfree(&glob_result);
    return files;
}

Эту функцию можно вызывать с обычным шаблоном wildcard, например:

vector<string> files = globVector("./*");
0

Вы можете использовать следующий фрагмент кода для перечисления всех файлов в директории:

#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>

int main(int argc, char** argv) { 
    list_dir("myFolderName");
    return EXIT_SUCCESS;
}  

static void list_dir(const char *path) {
    struct dirent *entry;
    DIR *dir = opendir(path);
    if (dir == NULL) {
        return;
    }

    while ((entry = readdir(dir)) != NULL) {
        printf("%s\n", entry->d_name);
    }

    closedir(dir);
}

В этом коде используется функция readdir, которая позволяет пройтись по всем файловым записям в указанной директории. Если opendir не удается открыть директорию, код просто возвращает управление. Обратите внимание, что функция не делает никаких проверок на наличие файлов, кроме проверки, была ли успешно открыта директория.

Структура, используемая в коде, определена в заголовочном файле dirent.h и выглядит следующим образом:

struct dirent {
    ino_t d_ino; /* номер inode */
    off_t d_off; /* смещение до следующей записи dirent */
    unsigned short d_reclen; /* длина этой записи */
    unsigned char d_type; /* тип файла */
    char d_name[256]; /* имя файла */
};

Вы можете использовать этот код, чтобы получить список файлов в выбранной директории, просто заменив "myFolderName" на нужный путь.

0

Вот очень простой код на C++11, использующий библиотеку boost::filesystem, чтобы получить имена файлов в директории (исключая имена папок):

#include <string>
#include <iostream>
#include <boost/filesystem.hpp>
using namespace std;
using namespace boost::filesystem;

int main()
{
    path p("D:/AnyFolder");
    for (auto i = directory_iterator(p); i != directory_iterator(); i++)
    {
        if (!is_directory(i->path())) // исключаем директории
        {
            cout << i->path().filename().string() << endl;
        }
        else
            continue;
    }
}

Вывод будет следующим:

file1.txt
file2.dat

Этот код создает итератор для указанной директории и проверяет каждую запись на то, является ли она папкой. Если запись не является папкой, имя файла выводится на экран.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь