Попробую использовать dirent.h, чтобы найти все файлы в подпапках C++

Я в настоящее время застрял с использованием расширения dirent.h. Цель состоит в том, чтобы дать функции каталог для начала. Затем эта функция просматривает все подпапки из этого каталога и находит в нем файлы. Все работает, пока в одной директории нет двух папок. Затем программа упорно выбирает одну папки и игнорирует другие. Здесь идет мой беспорядок кода. (Проблема прокомментирована внизу кода)

    #include <iostream>
    #include "dirent.h"
    #include <windows.h>

    DWORD getPathType(const char *path); //checks if path leads to folder or file
    const char *dirlist[20];  //contains all directories (not files, only dir's)
    int dirAm = 0;            //specifies amount of directories

    void loadTextures(const char *loaddir) {

        dirlist[dirAm] = loaddir;  //specifies starting directory
        dirAm++;

        for(int i = 0; i<20; i++) {
            DIR *dir;
            struct dirent *ent;
            const char *currentdir = dirlist[i];  //stores current directory
            dir = opendir(currentdir);            //opens current directory

            if (dir != NULL) {
                std::cout << "[OPENING dir]\t" << currentdir << std::endl;

                while ((ent = readdir(dir)) != NULL) {
                    const char *filename;  //stores current file/folder name
                    char fullDirName[100]; //stores full path name (current dir+file name, for example /images/+image1.png)
                    DWORD filetype;        //checking path type (file/folder)
                    filename = ent->d_name; //gets current file name

                    strcpy(fullDirName, currentdir); //concats current directory and file name to get full path, for example /images/image1.png
                    strcat(fullDirName, filename);

                    filetype = getPathType(fullDirName); //gets path type
                    if (filetype == FILE_ATTRIBUTE_DIRECTORY) {
                        //if its a directory add it to the list of directories, dirlist, the naming process is the same as above
                        const char *filenameIn;
                        char fullDirNameIn[100];

                        filenameIn = ent->d_name;

                        strcpy(fullDirNameIn, currentdir);
                        strcat(fullDirNameIn, filenameIn);
                        strcat(fullDirNameIn, "/");
                        std::cout << "[FOUND dir]\t" << fullDirNameIn<<std::endl;

                        dirlist[dirAm] = fullDirNameIn;
                        dirAm++;

                        /* Here is the problem! The cout line above finds all
 folders in a directory and saves them in the array, but as soon as the new for
 loop iteration starts, the values in the dirlist array... change? And I have no
 idea what is going on */

                    } else {
                        std::cout << "[FOUND file]\t" << fullDirName << std::endl;
                    }
                }
            }
        }

А вот и функция getPathType(). Я полагаю, довольно прямо.

DWORD getPathType(const char *path) {
    DWORD fileat;
    fileat = GetFileAttributesA(path);
    return fileat;
}

Наконец, вот вывод консоли:

[OPENING dir]   img/                 <- opens starting dir
[FOUND dir]     img/lvl0/            <- finds lvl0, should store it in dirlist
[FOUND dir]     img/lvl1/            <- finds lvl1
[OPENING dir]   img/lvl1/
[FOUND file]    img/lvl1/player2.png
[OPENING dir]   img/lvl1/            <- only opens lvl1
[FOUND file]    img/lvl1/player2.png

Я знаю, что это очень большой вопрос, но я был бы весьма благодарен, если бы кто-то мог поделиться идеями по этому вопросу.

1 ответ

Решение

Вы игнорируете область действия ваших массивов символов. Эффективно вы делаете это

const char *dirlist[20];

while (...)
{
    char fullDirNameIn[100];
    ....
    dirlist[dirAm] = fullDirNameIn;
}

Проблема в том, что ваш массив ограничен телом цикла while, но вы храните указатель на этот массив вне цикла while. После выхода из тела цикла (то есть, когда вы выполняете итерацию) содержимое вашего массива становится неопределенным, но у вас все еще есть указатель на него.

Решение легко, и этот урок должен быть хорошо усвоен. Не используйте указатели, делайте то, что делают и используют опытные программисты std::string вместо.

std::string dirlist[20];

while (...)
{
    std::string fullDirNameIn;
    ....
    dirlist[dirAm] = fullDirNameIn;
}
Другие вопросы по тегам