How to list all subdirectories in a given directory in C?

Is there a way to list all subdirectories in a given directory path in C? I was hoping I could do this using the stat() function, but it only works with files.

+4
source share
4 answers

stat also works in directories.

 #include <sys/types.h> #include <dirent.h> #include <sys/stat.h> #include <unistd.h> int num_dirs(const char* path) { int dir_count = 0; struct dirent* dent; DIR* srcdir = opendir(path); if (srcdir == NULL) { perror("opendir"); return -1; } while((dent = readdir(srcdir)) != NULL) { struct stat st; if(strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) continue; if (fstatat(dirfd(srcdir), dent->d_name, &st, 0) < 0) { perror(dent->d_name); continue; } if (S_ISDIR(st.st_mode)) dir_count++; } closedir(srcdir); return dir_count; } 

+8
source

You want readdir (3) .

+5
source

As others have noted, stat(2) works great with files and devices of all types. It reads symbolic links to the file at the far end; if you need information about the symbolic link itself, use lstat(2) .

To list the names of all directories within the same directory (non-recursively), use a combination of readdir(3) function families.

To list the names of all directories recursively, use the ftw(3) or nftw(3) functions to perform a "walk through the file tree" (where they find their names; "n" is "new").

+2
source
 /* I had need in something like this not so long ago (my difference is I needed recursive scan) so I added only some comments... Sorry for recursion but I was short of time and this was only part of internal one-time tool. */ /* Print all the dirs starting from <path> [maybe recursive]. */ int print_dirs(const char *path, int recursive) { struct dirent *direntp = NULL; DIR *dirp = NULL; size_t path_len; /* Check input parameters. */ if (!path) return -1; path_len = strlen(path); if (!path || !path_len || (path_len > _POSIX_PATH_MAX)) return -1; /* Open directory */ dirp = opendir(path); if (dirp == NULL) return -1; while ((direntp = readdir(dirp)) != NULL) { /* For every directory entry... */ struct stat fstat; char full_name[_POSIX_PATH_MAX + 1]; /* Calculate full name, check we are in file length limts */ if ((path_len + strlen(direntp->d_name) + 1) > _POSIX_PATH_MAX) continue; strcpy(full_name, path); if (full_name[path_len - 1] != '/') strcat(full_name, "/"); strcat(full_name, direntp->d_name); /* Ignore special directories. */ if ((strcmp(direntp->d_name, ".") == 0) || (strcmp(direntp->d_name, "..") == 0)) continue; /* Print only if it is really directory. */ if (stat(full_name, &fstat) < 0) continue; if (S_ISDIR(fstat.st_mode)) { printf("%s\n", full_name); if (recursive) print_dirs(full_name, 1); } } /* Finalize resources. */ (void)closedir(dirp); return 0; } /* We are taking first argument as initial path name. */ int main(int argc, const char* argv[]) { if (argc < 2) return -1; print_dirs(argv[1], 1); return 0; } 
+2
source

All Articles