Logo

How can I get the list of files in a directory using C or C++?

Several approaches exist for enumerating files in a directory, depending on your platform and which libraries you’re allowed to use. Below are three common methods:

  1. POSIX/Unix Approach (opendir, readdir, closedir)
  2. Windows-Specific API (FindFirstFile, FindNextFile)
  3. C++17 std::filesystem (portable across modern compilers)

1. POSIX/Unix Approach: opendir / readdir / closedir

Works on: Linux, macOS, and other Unix-like systems.

Example

#include <stdio.h> #include <dirent.h> #include <string.h> int main(void) { const char *path = "."; // current directory DIR *dir = opendir(path); if (!dir) { perror("opendir"); return 1; } struct dirent *entry; while ((entry = readdir(dir)) != NULL) { // Skip "." and ".." if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { continue; } printf("%s\n", entry->d_name); } closedir(dir); return 0; }
  • Key Functions:

    • opendir(path): Opens a directory stream.
    • readdir(dir): Returns a pointer to the next directory entry (struct dirent).
    • closedir(dir): Closes the directory stream.
  • Check entry->d_type (if supported) to see if it’s a file, directory, etc. Alternatively, do an additional stat call to query file info.

2. Windows-Specific API: FindFirstFile / FindNextFile

Works on: Microsoft Windows.
Header: <windows.h>

Example

#include <windows.h> #include <tchar.h> // For _T() macro (if you use it) #include <iostream> int main() { WIN32_FIND_DATA findData; HANDLE hFind = INVALID_HANDLE_VALUE; // Build the search pattern (e.g., "C:\\path\\to\\directory\\*") const char* directory = "C:\\path\\to\\directory\\*"; hFind = FindFirstFile(directory, &findData); if (hFind == INVALID_HANDLE_VALUE) { std::cerr << "FindFirstFile failed.\n"; return 1; } do { // Skip "." and ".." if (strcmp(findData.cFileName, ".") == 0 || strcmp(findData.cFileName, "..") == 0) { continue; } std::cout << findData.cFileName << "\n"; } while (FindNextFile(hFind, &findData) != 0); FindClose(hFind); return 0; }
  • Key Functions:
    • FindFirstFile(searchPattern, &findData): Returns a handle and populates findData with the first file.
    • FindNextFile(handle, &findData): Updates findData with the next file until no more files are found.
    • FindClose(handle): Closes the search handle.

3. C++17 std::filesystem (Portable)

Works on: Systems with C++17 or later support, including modern Windows, Linux, macOS compilers.

Example

#include <iostream> #include <filesystem> // C++17 namespace fs = std::filesystem; int main() { std::string path = "."; try { for (const auto &entry : fs::directory_iterator(path)) { std::cout << entry.path().filename().string() << "\n"; } } catch (const fs::filesystem_error& e) { std::cerr << "Error: " << e.what() << "\n"; return 1; } return 0; }
  • Advantages:
    • Cross-platform (where C++17 filesystem is supported).
    • Provides higher-level operations (checking file type, size, etc.) via fs::directory_entry.

Notes & Tips

  1. Filtering

    • Often, you’ll want to skip . and .. or filter out subdirectories. On Unix, use entry->d_type or stat. On Windows, check findData.dwFileAttributes for FILE_ATTRIBUTE_DIRECTORY.
    • In C++17, fs::is_directory(entry.status()) or similar calls are available.
  2. Error Handling

    • Always handle failures (e.g., cannot open directory, invalid path).
    • Check errno on POSIX or GetLastError() on Windows for specific error codes.
  3. Large Directories

    • Directories with many files require a loop reading all entries.
    • On Windows, you might need to handle long paths or Unicode file names (e.g., using FindFirstFileW with wide strings).

Want to Master System-Level Programming?

For a deeper dive into how operating systems handle files, directories, memory, and beyond—and to prepare for tough technical interviews—two recommended courses from DesignGurus.io:

By getting comfortable with the native APIs (opendir, readdir, or FindFirstFile) or the modern C++17 std::filesystem approach, you’ll be equipped to handle file-system-related tasks robustly and efficiently in your C/C++ projects.

CONTRIBUTOR
TechGrind