Попробую использовать 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;
}