168

How do you iterate through every file/directory recursively in standard C++?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
robottobor
  • 11,595
  • 11
  • 39
  • 37
  • 2
    Not standard C++: http://pocoproject.org/docs/Poco.DirectoryIterator.html – Agnel Kurian Jun 01 '10 at 07:01
  • 2
    This should soon be in the standard via the [Filesystem TS](http://en.cppreference.com/w/cpp/experimental/fs), with the [recursive_directory_iterator](http://en.cppreference.com/w/cpp/experimental/fs/recursive_directory_iterator) – Adi Shavit Feb 17 '16 at 15:02
  • 1
    If use of a standard C library doesn't get in the way of calling a C++ program as 'standard', [nftw()](https://linux.die.net/man/3/nftw). Here's a practical [example](https://github.com/six-k/dtreetrawl/blob/f7c1d320225ee754b96fef28bb0774a2c34b91b8/dtreetrawl.c#L473) – six-k Jan 07 '18 at 10:36
  • You may want to examine boost.filesystem http://www.boost.org/doc/libs/1_31_0/libs/filesystem/doc/index.htm – Doug T. Sep 15 '08 at 21:44
  • 3
    Somebody, who knows what they're doing, should take an hour to update this. – Josh C Dec 28 '18 at 06:32
  • The trouble with all the range-based "beauty-shot" answers is that it's unsuitable for serious production use, for the lack of per-iteration error recovery. It's all or nothing. By the time you catch an exception, the loop is gone. OTOH, if you want to protect all the fragile parts individually, horror ensues: the loop has to be dissected, and the result won't resemble anything remotely pretty -- and the `++` op (`increment()`) could _still_ fail irrecoverably... That (and related crashes deemed too costly to debug) was when I abandoned the std rec. dir-iterator altogether, as "still a toy". – Sz. Jul 25 '19 at 23:14

19 Answers19

125

From C++17 onward, the <filesystem> header, and range-for, you can simply do this:

#include <filesystem>

using recursive_directory_iterator = std::filesystem::recursive_directory_iterator;
...
for (const auto& dirEntry : recursive_directory_iterator(myPath))
     std::cout << dirEntry << std::endl;

As of C++17, std::filesystem is part of the standard library and can be found in the <filesystem> header (no longer "experimental").

Adi Shavit
  • 16,743
  • 5
  • 67
  • 137
104

In standard C++, technically there is no way to do this since standard C++ has no conception of directories. If you want to expand your net a little bit, you might like to look at using Boost.FileSystem. This has been accepted for inclusion in TR2, so this gives you the best chance of keeping your implementation as close as possible to the standard.

An example, taken straight from the website:

bool find_file( const path & dir_path,         // in this directory,
                const std::string & file_name, // search for this name,
                path & path_found )            // placing path here if found
{
  if ( !exists( dir_path ) ) return false;
  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()) )
    {
      if ( find_file( itr->path(), file_name, path_found ) ) return true;
    }
    else if ( itr->leaf() == file_name ) // see below
    {
      path_found = itr->path();
      return true;
    }
  }
  return false;
}
1800 INFORMATION
  • 131,367
  • 29
  • 160
  • 239
  • 7
    C++ has no concept of files? What about std::fstream? Or fopen? – Kevin Sep 15 '08 at 22:03
  • 24
    Update with regard to latest boost version: In case anyone stumbles across this answer, the latest boost includes a convenience class boost::recursive_directory_iterator so writing the above loop with explicit recursive call is no longer necessary. Link: http://www.boost.org/doc/libs/1_46_1/libs/filesystem/v3/doc/reference.html#Class-recursive_directory_iterator – JasDev Jun 05 '11 at 19:51
  • 1
    You should probably replace itr->leaf() with itr->path().leaf() ('leaf' : is not a member of 'boost::filesystem::directory_entry') – kFk Aug 03 '12 at 13:46
  • 6
    VC++11 comes with much the same functionality in the header under the std::tr2::sys namespace. – mheyman Aug 30 '13 at 12:27
  • I haven't written actual C++ code in ages. Someone who is more up to date should edit this to be more modern – 1800 INFORMATION Oct 05 '15 at 01:12
  • [`std::filesystem`](http://en.cppreference.com/w/cpp/filesystem) is finally included in the ISO standard as of **C++17**. – zett42 Nov 30 '17 at 22:40
  • No need for boost. The OP specifically asked for standard c++. – Craig B May 16 '18 at 23:46
  • 12
    This used to be a good answer, but now that is standard, it's better to simply use is (see other answers for an example). – Gathar Aug 12 '19 at 14:01
  • Instead of the deprecated `leaf()`, use `path().filename()`. https://www.boost.org/doc/libs/1_64_0/libs/filesystem/doc/deprecated.html – Pulseczar Sep 02 '22 at 18:11
52

If using the Win32 API you can use the FindFirstFile and FindNextFile functions.

http://msdn.microsoft.com/en-us/library/aa365200(VS.85).aspx

For recursive traversal of directories you must inspect each WIN32_FIND_DATA.dwFileAttributes to check if the FILE_ATTRIBUTE_DIRECTORY bit is set. If the bit is set then you can recursively call the function with that directory. Alternatively you can use a stack for providing the same effect of a recursive call but avoiding stack overflow for very long path trees.

#include <windows.h>
#include <string>
#include <vector>
#include <stack>
#include <iostream>

using namespace std;

bool ListFiles(wstring path, wstring mask, vector<wstring>& files) {
    HANDLE hFind = INVALID_HANDLE_VALUE;
    WIN32_FIND_DATA ffd;
    wstring spec;
    stack<wstring> directories;

    directories.push(path);
    files.clear();

    while (!directories.empty()) {
        path = directories.top();
        spec = path + L"\\" + mask;
        directories.pop();

        hFind = FindFirstFile(spec.c_str(), &ffd);
        if (hFind == INVALID_HANDLE_VALUE)  {
            return false;
        } 

        do {
            if (wcscmp(ffd.cFileName, L".") != 0 && 
                wcscmp(ffd.cFileName, L"..") != 0) {
                if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                    directories.push(path + L"\\" + ffd.cFileName);
                }
                else {
                    files.push_back(path + L"\\" + ffd.cFileName);
                }
            }
        } while (FindNextFile(hFind, &ffd) != 0);

        if (GetLastError() != ERROR_NO_MORE_FILES) {
            FindClose(hFind);
            return false;
        }

        FindClose(hFind);
        hFind = INVALID_HANDLE_VALUE;
    }

    return true;
}

int main(int argc, char* argv[])
{
    vector<wstring> files;

    if (ListFiles(L"F:\\cvsrepos", L"*", files)) {
        for (vector<wstring>::iterator it = files.begin(); 
             it != files.end(); 
             ++it) {
            wcout << it->c_str() << endl;
        }
    }
    return 0;
}
ChrisN
  • 16,635
  • 9
  • 57
  • 81
Jorge Ferreira
  • 96,051
  • 25
  • 122
  • 132
  • 23
    how long did it take you to write that? I think it would take less time to glue C++ to python and do it in one line. – Dustin Getz Oct 24 '08 at 14:00
  • 4
    This is a nice, non-recursive solution (which is sometimes handy!). – jm. Jun 09 '09 at 20:43
  • 2
    Btw, if anyone wants to edit the program slightly to accept a command-line parameter argv[1] for the path instead of a hardcoded one ("F:\\cvsrepos"), the signature for main(int, char) would change to wmain(int, wchar_t) like this: int wmain(int argc, wchar_t *argv[]) – JasDev Jun 02 '11 at 10:18
  • 2
    Thanks, but this function does not work with Cyrilic. Is there any way to make it work with Cyrilic characters like - б, в, г etc ? – unresolved_external Aug 01 '12 at 19:29
35

You can make it even simpler with the new C++11 range based for and Boost:

#include <boost/filesystem.hpp>

using namespace boost::filesystem;    
struct recursive_directory_range
{
    typedef recursive_directory_iterator iterator;
    recursive_directory_range(path p) : p_(p) {}

    iterator begin() { return recursive_directory_iterator(p_); }
    iterator end() { return recursive_directory_iterator(); }

    path p_;
};

for (auto it : recursive_directory_range(dir_path))
{
    std::cout << it << std::endl;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Matthieu G
  • 794
  • 7
  • 9
28

A fast solution is using C's Dirent.h library.

Working code fragment from Wikipedia:

#include <stdio.h>
#include <dirent.h>

int listdir(const char *path) {
    struct dirent *entry;
    DIR *dp;

    dp = opendir(path);
    if (dp == NULL) {
        perror("opendir: Path does not exist or could not be read.");
        return -1;
    }

    while ((entry = readdir(dp)))
        puts(entry->d_name);

    closedir(dp);
    return 0;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alex
  • 2,145
  • 3
  • 19
  • 19
12

You can use std::filesystem::recursive_directory_iterator. But beware, this includes symbolic (soft) links. If you want to avoid them you can use is_symlink. Example usage:

size_t directory_size(const std::filesystem::path& directory)
{
    size_t size{ 0 };
    for (const auto& entry : std::filesystem::recursive_directory_iterator(directory))
    {
        if (entry.is_regular_file() && !entry.is_symlink())
        {
            size += entry.file_size();
        }
    }
    return size;
}
pooya13
  • 2,060
  • 2
  • 23
  • 29
11

In addition to the above mentioned boost::filesystem you may want to examine wxWidgets::wxDir and Qt::QDir.

Both wxWidgets and Qt are open source, cross platform C++ frameworks.

wxDir provides a flexible way to traverse files recursively using Traverse() or a simpler GetAllFiles() function. As well you can implement the traversal with GetFirst() and GetNext() functions (I assume that Traverse() and GetAllFiles() are wrappers that eventually use GetFirst() and GetNext() functions).

QDir provides access to directory structures and their contents. There are several ways to traverse directories with QDir. You can iterate over the directory contents (including sub-directories) with QDirIterator that was instantiated with QDirIterator::Subdirectories flag. Another way is to use QDir's GetEntryList() function and implement a recursive traversal.

Here is sample code (taken from here # Example 8-5) that shows how to iterate over all sub directories.

#include <qapplication.h>
#include <qdir.h>
#include <iostream>

int main( int argc, char **argv )
{
    QApplication a( argc, argv );
    QDir currentDir = QDir::current();

    currentDir.setFilter( QDir::Dirs );
    QStringList entries = currentDir.entryList();
    for( QStringList::ConstIterator entry=entries.begin(); entry!=entries.end(); ++entry) 
    {
         std::cout << *entry << std::endl;
    }
    return 0;
}
tonymontana
  • 5,728
  • 4
  • 34
  • 53
  • 1
    Doxygen uses QT as its OS compatibility layer. The core tools doesn't use a GUI at all just the directory stuff (and others compenents). – deft_code Jul 09 '10 at 06:39
9

Boost::filesystem provides recursive_directory_iterator, which is quite convenient for this task:

#include "boost/filesystem.hpp"
#include <iostream>

using namespace boost::filesystem;

recursive_directory_iterator end;
for (recursive_directory_iterator it("./"); it != end; ++it) {
    std::cout << *it << std::endl;                                    
}
DikobrAz
  • 3,557
  • 4
  • 35
  • 53
  • 2
    What is "it" please? Isn't there a syntax error? And how do you feed the "end"? (=how know we parsed all the dir?) – yO_ Jun 13 '18 at 12:12
  • 2
    @yO_ you're right there was a typo, default constructor for recursive_directory_iterator will construct an "invalid" iterator, when you finished iterating over dir it will turn "it" will become invalid and will be equal to "end" – DikobrAz Jun 13 '18 at 16:25
8

You can use ftw(3) or nftw(3) to walk a filesystem hierarchy in C or C++ on POSIX systems.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
leif
  • 1,987
  • 4
  • 19
  • 22
  • 2
    https://github.com/six-k/dtreetrawl/blob/f7c1d320225ee754b96fef28bb0774a2c34b91b8/dtreetrawl.c#L473 has an example of this. The code does a few more stuff, but it acts a good tutorial for `nftw()` usage. – six-k Jan 07 '18 at 10:29
7

We are in 2019. We have filesystem standard library in C++. The Filesystem library provides facilities for performing operations on file systems and their components, such as paths, regular files, and directories.

There is an important note on this link if you are considering portability issues. It says:

The filesystem library facilities may be unavailable if a hierarchical file system is not accessible to the implementation, or if it does not provide the necessary capabilities. Some features may not be available if they are not supported by the underlying file system (e.g. the FAT filesystem lacks symbolic links and forbids multiple hardlinks). In those cases, errors must be reported.

The filesystem library was originally developed as boost.filesystem, was published as the technical specification ISO/IEC TS 18822:2015, and finally merged to ISO C++ as of C++17. The boost implementation is currently available on more compilers and platforms than the C++17 library.

@adi-shavit has answered this question when it was part of std::experimental and he has updated this answer in 2017. I want to give more details about the library and show more detailed example.

std::filesystem::recursive_directory_iterator is an LegacyInputIterator that iterates over the directory_entry elements of a directory, and, recursively, over the entries of all subdirectories. The iteration order is unspecified, except that each directory entry is visited only once.

If you don't want to recursively iterate over the entries of subdirectories, then directory_iterator should be used.

Both iterators returns an object of directory_entry. directory_entry has various useful member functions like is_regular_file, is_directory, is_socket, is_symlink etc. The path() member function returns an object of std::filesystem::path and it can be used to get file extension, filename, root name.

Consider the example below. I have been using Ubuntu and compiled it over the terminal using

g++ example.cpp --std=c++17 -lstdc++fs -Wall

#include <iostream>
#include <string>
#include <filesystem>

void listFiles(std::string path)
{
    for (auto& dirEntry: std::filesystem::recursive_directory_iterator(path)) {
        if (!dirEntry.is_regular_file()) {
            std::cout << "Directory: " << dirEntry.path() << std::endl;
            continue;
        }
        std::filesystem::path file = dirEntry.path();
        std::cout << "Filename: " << file.filename() << " extension: " << file.extension() << std::endl;

    }
}

int main()
{
    listFiles("./");
    return 0;
}
abhiarora
  • 9,743
  • 5
  • 32
  • 57
6

You would probably be best with either boost or c++14's experimental filesystem stuff. IF you are parsing an internal directory (ie. used for your program to store data after the program was closed), then make an index file that has an index of the file contents. By the way, you probably would need to use boost in the future, so if you don't have it installed, install it! Second of all, you could use a conditional compilation, e.g.:

#ifdef WINDOWS //define WINDOWS in your code to compile for windows
#endif

The code for each case is taken from https://stackoverflow.com/a/67336/7077165

#ifdef POSIX //unix, linux, etc.
#include <stdio.h>
#include <dirent.h>

int listdir(const char *path) {
    struct dirent *entry;
    DIR *dp;

    dp = opendir(path);
    if (dp == NULL) {
        perror("opendir: Path does not exist or could not be read.");
        return -1;
    }

    while ((entry = readdir(dp)))
        puts(entry->d_name);

    closedir(dp);
    return 0;
}
#endif
#ifdef WINDOWS
#include <windows.h>
#include <string>
#include <vector>
#include <stack>
#include <iostream>

using namespace std;

bool ListFiles(wstring path, wstring mask, vector<wstring>& files) {
    HANDLE hFind = INVALID_HANDLE_VALUE;
    WIN32_FIND_DATA ffd;
    wstring spec;
    stack<wstring> directories;

    directories.push(path);
    files.clear();

    while (!directories.empty()) {
        path = directories.top();
        spec = path + L"\\" + mask;
        directories.pop();

        hFind = FindFirstFile(spec.c_str(), &ffd);
        if (hFind == INVALID_HANDLE_VALUE)  {
            return false;
        } 

        do {
            if (wcscmp(ffd.cFileName, L".") != 0 && 
                wcscmp(ffd.cFileName, L"..") != 0) {
                if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                    directories.push(path + L"\\" + ffd.cFileName);
                }
                else {
                    files.push_back(path + L"\\" + ffd.cFileName);
                }
            }
        } while (FindNextFile(hFind, &ffd) != 0);

        if (GetLastError() != ERROR_NO_MORE_FILES) {
            FindClose(hFind);
            return false;
        }

        FindClose(hFind);
        hFind = INVALID_HANDLE_VALUE;
    }

    return true;
}
#endif
//so on and so forth.
ndrewxie
  • 172
  • 3
  • 10
5

You don't. The C++ standard has no concept of directories. It is up to the implementation to turn a string into a file handle. The contents of that string and what it maps to is OS dependent. Keep in mind that C++ can be used to write that OS, so it gets used at a level where asking how to iterate through a directory is not yet defined (because you are writing the directory management code).

Look at your OS API documentation for how to do this. If you need to be portable, you will have to have a bunch of #ifdefs for various OSes.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Matthew Scouten
  • 15,303
  • 9
  • 33
  • 50
3

You need to call OS-specific functions for filesystem traversal, like open() and readdir(). The C standard does not specify any filesystem-related functions.

John Millikin
  • 197,344
  • 39
  • 212
  • 226
2

On C++17 you can by this way :

#include <filesystem>
#include <iostream>
#include <vector>
namespace fs = std::filesystem;

int main()
{
    std::ios_base::sync_with_stdio(false);
    for (const auto &entry : fs::recursive_directory_iterator(".")) {
        if (entry.path().extension() == ".png") {
            std::cout << entry.path().string() << std::endl;
            
        }
    }
    return 0;
}
Bensuperpc
  • 1,275
  • 1
  • 14
  • 21
2

You don't. Standard C++ doesn't expose to concept of a directory. Specifically it doesn't give any way to list all the files in a directory.

A horrible hack would be to use system() calls and to parse the results. The most reasonable solution would be to use some kind of cross-platform library such as Qt or even POSIX.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
shoosh
  • 76,898
  • 55
  • 205
  • 325
1

If you are on Windows, you can use the FindFirstFile together with FindNextFile API. You can use FindFileData.dwFileAttributes to check if a given path is a file or a directory. If it's a directory, you can recursively repeat the algorithm.

Here, I have put together some code that lists all the files on a Windows machine.

http://dreams-soft.com/projects/traverse-directory

Ibrahim
  • 837
  • 2
  • 13
  • 24
0

File tree walk ftw is a recursive way to wall the whole directory tree in the path. More details are here.

NOTE : You can also use fts that can skip hidden files like . or .. or .bashrc

#include <ftw.h>
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>

 
int list(const char *name, const struct stat *status, int type)
{
     if (type == FTW_NS)
     {
         return 0;
     }

     if (type == FTW_F)
     {
         printf("0%3o\t%s\n", status->st_mode&0777, name);
     }

     if (type == FTW_D && strcmp(".", name) != 0)
     {
         printf("0%3o\t%s/\n", status->st_mode&0777, name);
     }
     return 0;
}

int main(int argc, char *argv[])
{
     if(argc == 1)
     {
         ftw(".", list, 1);
     }
     else
     {
         ftw(argv[1], list, 1);
     }

     return 0;
}

output looks like following:

0755    ./Shivaji/
0644    ./Shivaji/20200516_204454.png
0644    ./Shivaji/20200527_160408.png
0644    ./Shivaji/20200527_160352.png
0644    ./Shivaji/20200520_174754.png
0644    ./Shivaji/20200520_180103.png
0755    ./Saif/
0644    ./Saif/Snapchat-1751229005.jpg
0644    ./Saif/Snapchat-1356123194.jpg
0644    ./Saif/Snapchat-613911286.jpg
0644    ./Saif/Snapchat-107742096.jpg
0755    ./Milind/
0644    ./Milind/IMG_1828.JPG
0644    ./Milind/IMG_1839.JPG
0644    ./Milind/IMG_1825.JPG
0644    ./Milind/IMG_1831.JPG
0644    ./Milind/IMG_1840.JPG

Let us say if you want to match a filename (example: searching for all the *.jpg, *.jpeg, *.png files.) for a specific needs, use fnmatch.

 #include <ftw.h>
 #include <stdio.h>
 #include <sys/stat.h>
 #include <iostream>
 #include <fnmatch.h>

 static const char *filters[] = {
     "*.jpg", "*.jpeg", "*.png"
 };

 int list(const char *name, const struct stat *status, int type)
 {
     if (type == FTW_NS)
     {
         return 0;
     }

     if (type == FTW_F)
     {
         int i;
         for (i = 0; i < sizeof(filters) / sizeof(filters[0]); i++) {
             /* if the filename matches the filter, */
             if (fnmatch(filters[i], name, FNM_CASEFOLD) == 0) {
                 printf("0%3o\t%s\n", status->st_mode&0777, name);
                 break;
             }
         }
     }

     if (type == FTW_D && strcmp(".", name) != 0)
     {
         //printf("0%3o\t%s/\n", status->st_mode&0777, name);
     }
     return 0;
 }

 int main(int argc, char *argv[])
 {
     if(argc == 1)
     {
         ftw(".", list, 1);
     }
     else
     {
         ftw(argv[1], list, 1);
     }

     return 0;
 }
Milind Deore
  • 2,887
  • 5
  • 25
  • 40
0

Answers of getting all file names recursively with C++11 for Windows and Linux(with experimental/filesystem):
For Windows:

#include <io.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <windows.h>
void getFiles_w(string path, vector<string>& files) {
    intptr_t hFile = 0; 
    struct _finddata_t fileinfo;  
    string p; 
    if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1) {
        do {
            if ((fileinfo.attrib & _A_SUBDIR)) {
                if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
                    getFiles(p.assign(path).append("/").append(fileinfo.name), files);
            }
            else {
                files.push_back(p.assign(path).append("/").append(fileinfo.name));
            }
        } while (_findnext(hFile, &fileinfo) == 0);
    }
}

For Linux:

#include <experimental/filesystem>
bool getFiles(std::experimental::filesystem::path path, vector<string>& filenames) {
    namespace stdfs = std::experimental::filesystem;
    // http://en.cppreference.com/w/cpp/experimental/fs/directory_iterator
    const stdfs::directory_iterator end{} ;
    
    for (stdfs::directory_iterator iter{path}; iter != end ; ++iter) {
        // http://en.cppreference.com/w/cpp/experimental/fs/is_regular_file 
        if (!stdfs::is_regular_file(*iter)) { // comment out if all names (names of directories tc.) are required 
            if (getFiles(iter->path(), filenames)) 
                return true;
        }
        else {
            filenames.push_back(iter->path().string()) ;
            cout << iter->path().string() << endl;  
        }
    }
    return false;
}

Just remember to link -lstdc++fs when you compile it with g++ in Linux.

Hu Xixi
  • 1,799
  • 2
  • 21
  • 29
0

Employee Visual C++ and WIN API:

bool Parser::queryDIR(string dir_name) {
    vector<string> sameLayerFiles;
    bool ret = false;
    string dir = "";
    //employee wide char
    dir = dir_name  + "\\*.*";;
    //employee WIN File API
    WIN32_FIND_DATA  fd;
    WIN32_FIND_DATA  fd_dir;
    HANDLE hFind = ::FindFirstFile(getWC(dir.c_str()), &fd);
    HANDLE hFind_dir = ::FindFirstFile(getWC(dir.c_str()), &fd_dir);
    string str_subdir;
    string str_tmp;
    //recursive call for diving into sub-directories
    do {
        if ((fd_dir.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
            //ignore trival file node
            while(true) {
                FindNextFile(hFind_dir, &fd_dir);
                str_tmp = wc2str(fd_dir.cFileName);
                if (str_tmp.compare(".") && str_tmp.compare("..")){
                    break;
                }
            }
            if ((fd_dir.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
                str_subdir = wc2str(fd_dir.cFileName);
                ret = queryDIR(dir_name + "\\" + str_subdir);
            }
        }
    } while(::FindNextFile(hFind_dir, &fd_dir));

    //iterate same layer files
    do { 
        if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
            str_tmp = wc2str(fd.cFileName);
            string fname = dir_name + "\\" + str_tmp;
            sameLayerFiles.push_back(fname);
        }
    } while(::FindNextFile(hFind, &fd));    

    for (std::vector<string>::iterator it=sameLayerFiles.begin(); it!=sameLayerFiles.end(); it++) {
        std::cout << "iterated file:" << *it << "..." << std::endl;
        //Doing something with every file here
    }
    return true;   
}

Hope my code can help :)

And you can see more details and program screen-shots on My GitHub

Mou
  • 145
  • 1
  • 6