Вы сталкиваетесь с проблемами, передавая указатель DIR*
и указатель struct dirent*
в качестве параметров вместо простого формирования и передачи следующего пути к открытию. Вы хотите обрабатывать открытие каталога внутри самой рекурсивной функции, а не как один указатель, переданный из main()
, например,
void print_dir_rec(const char *name)
{
DIR *dir;
struct dirent *entry;
if (!(dir = opendir(name)))
return;
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR) {
char path[1024];
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
snprintf(path, sizeof(path), "%s/%s", name, entry->d_name);
printf("[%s]\n", entry->d_name);
print_dir_rec(path);
}
}
closedir(dir);
}
( примечание: вы можете настроить числосимволов, предоставленных для path
при необходимости или с помощью макроса PATH_MAX
)
Таким образом, не существует единственного указателя, который будет повторно использоваться в каждом рекурсивном вызове, вызывающем проблемы. Короткий пример, в котором перечислены все каталоги под текущим, может быть:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
void print_dir_rec(const char *name)
{
DIR *dir;
struct dirent *entry;
if (!(dir = opendir(name)))
return;
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR) {
char path[1024];
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
snprintf(path, sizeof(path), "%s/%s", name, entry->d_name);
printf("[%s]\n", entry->d_name);
print_dir_rec(path);
}
}
closedir(dir);
}
int main(void) {
print_dir_rec(".");
return 0;
}
Посмотрите, как обрабатываются открытия и чтения и какую информацию требуется передавать. Предоставляя хранилище для path
в рамках каждого рекурсивного вызова, вы гарантируете, что имя остается в области действия до тех пор, пока этот рекурсивный вызов не вернется.
Дайте мне знать, если у вас есть дополнительные вопросы.