I want to list folders in a directory in C++, ideally in a portable (working in the major Operating Systems) way. I tried using POSIX, and it works correctly, but how can i identify whether the found item is a folder?
6 Answers
You could use opendir()
and readdir()
to list directories and subdirectories. The following example prints all subdirectories inside the current path:
#include <dirent.h>
#include <stdio.h>
int main()
{
const char* PATH = ".";
DIR *dir = opendir(PATH);
struct dirent *entry = readdir(dir);
while (entry != NULL)
{
if (entry->d_type == DT_DIR)
printf("%s\n", entry->d_name);
entry = readdir(dir);
}
closedir(dir);
return 0;
}

- 2,663
- 3
- 24
- 41
-
You can select only folders by using these functions. I have added an example to show you how. – David Feb 18 '11 at 16:12
-
1[Error] 'struct dirent' has no member named 'd_type' . why do I get this error ? – Faridzs Dec 17 '15 at 21:04
-
Thanks for this great anwser. I'm using linux and I want to how to list linked directories, please. – Erman Dec 12 '16 at 16:41
-
@Faridzs See https://stackoverflow.com/a/39430337/1279291 – andreasdr Apr 17 '21 at 22:16
-
@andreasdr wow, that comment was written around 5 years ago :)) Thanks anyway! – Faridzs Apr 19 '21 at 06:44
Using the C++17 std::filesystem
library:
std::vector<std::string> get_directories(const std::string& s)
{
std::vector<std::string> r;
for(auto& p : std::filesystem::recursive_directory_iterator(s))
if (p.is_directory())
r.push_back(p.path().string());
return r;
}

- 10,717
- 5
- 39
- 72
-
I believe that since this is more portable way and still doesn't use any external libraries, it deserves more to be an accepted answer now. – m4tx Jan 29 '18 at 13:15
-
I get Segmentation faults once I cross the local application path. Eg. List the directories of /home/$USER. is this just me or this filesystem very unstable on my system? – Melroy van den Berg Jun 07 '19 at 00:31
-
2I believe `p.status().type() == std::filesystem::file_type::directory` can be replaced with `p.is_directory()`, unless there are subtle differences I'm unaware of. – Tim M. Jul 08 '19 at 18:30
Here follows a (slightly modified) quote from the boost filesystem documentation to show you how it can be done:
void iterate_over_directories( const path & dir_path ) // in this directory,
{
if ( exists( dir_path ) )
{
directory_iterator end_itr; // default construction yields past-the-end
for ( directory_iterator itr( dir_path );
itr != end_itr;
++itr )
{
if ( is_directory(itr->status()) )
{
//... here you have a directory
}
}
}
}

- 16,798
- 8
- 46
- 66
-
-
Note that `boost::filesystem` needs to be built. It is not headers-only. – Martín De la Fuente Nov 18 '19 at 23:46
Look up the stat
function. Here is a description. Some sample code:
struct stat st;
const char *dirname = "dir_name";
if( stat( dirname, &st ) == 0 && S_ISDIR( st.st_mode ) ) {
// "dir_name" is a subdirectory of the current directory
} else {
// "dir_name" doesn't exist or isn't a directory
}

- 56,086
- 21
- 82
- 121
I feel compelled to mention PhysFS. I just integrated it into my own project. It provides true cross-platform (Mac / Linux / PC) file operations and can even unpack various archive definitions such as zip, 7zip, pak, and so on. It has a few functions (PHYSFS_isDirectory, PHYSFS_enumerateFiles) which can determine what you are asking for as well.

- 5,355
- 2
- 18
- 30
Under Windows, you can use _findfirst() and _findnext() to iterate through the contents of a directory, and then use CreateFile() and GetFileInformationByHandle() to determine whether a particular entry is a directory or a folder. (Yes, CreateFile(), with the appropriate arguments, to examine an existing file. Ain't life grand?)
For reference, some classes where I implemented code that uses those calls can be seen here and here

- 70,199
- 15
- 131
- 234