K.Rejepow
K.Rejepow

Reputation: 25

How to get all files in a folder and its subfolders names&paths to string array on c++?

I am making a program and I need to get all files names and paths to string array.I can get files and folders path's by doing so:

HANDLE hFind;
WIN32_FIND_DATA data;
string folder="C:\\*.*";
int num=0;
string addresses[1000];
hFind=FindFirstFile(folder.c_str(),&data);
if(hFind!=INVALID_HANDLE_VALUE){
do{
    addresses[num]=folder.substr(0,folder.length()-3);
    addresses[num]+=data.cFileName;
    num++;
    }while(FindNextFile(hFind,&data));
FindClose(hFind);}

But it only gets files and folder names paths only in that folder.I need to get all files of that folder and it's subfolders.How can I do it?If possible please make it with function returning string array.

Upvotes: 0

Views: 865

Answers (1)

Daniel Sęk
Daniel Sęk

Reputation: 2769

Refactor your code into function and call it recursively when you get directory entry (remember to skip . and ..). Directory can be detected by checking if directory bit is set in data.dwFileAttributes (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY).

Don't do it on C: because you will have to wait a long time. For development create directory C:\Tests and place there few files and folders.

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

using namespace std;

// TODO: needs proper error checking, for example when given not existing path.

void GetFilesR( vector<string>& result, const char* path )
{
    HANDLE hFind;
    WIN32_FIND_DATA data;
    string folder( path );
    folder += "\\";
    string mask( folder );
    mask += "*.*";

    hFind=FindFirstFile(mask.c_str(),&data);
    if(hFind!=INVALID_HANDLE_VALUE)
    {
        do
        {
            string  name( folder );
            name += data.cFileName;
            if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
            {
                // Skip . and .. pseudo folders.
                if ( strcmp( data.cFileName, "." ) != 0 && strcmp( data.cFileName, ".." ) != 0 )
                {
                    // TODO: if you want directories appended to result, do it here.

                    // Add all files from this directory.
                    GetFilesR( result, name.c_str() );
                }
            }
            else
            {
                result.push_back( name );
            }
        } while(FindNextFile(hFind,&data));
    }
    FindClose(hFind);
}

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

    // TODO: change directory below.
    GetFilesR( files, "C:\\Tests" );
    // Print collected files.
    for ( vector<string>::iterator i = files.begin() ; i != files.end() ; ++i )
        cout << *i << "\n";
    return 0;
}

using namespace std, can be removed if you replace all instances off vector width std::vector, string with std::string an cout with std::cout.

Upvotes: 2

Related Questions