0

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.

Ron
  • 14,674
  • 4
  • 34
  • 47
K.Rejepow
  • 25
  • 1
  • 5
  • 1
    To begin with, you should probably use a `std::vector` instead of an array. To continue you should probably learn about *recursion*. This is a situation that's perfect for recursive functions. – Some programmer dude Oct 01 '17 at 10:33
  • As a sidenote: these are WinAPI calls and will only work on Windows OS. On Linux you would have to utilize a completely different set of functions. – Ron Oct 01 '17 at 10:39
  • 1
    A portable way to enumerate directory contents is to use C++17 `std::filesystem`. Or Boost filesystem. Being very careful about explicitly requesting/specifying UTF-8 everywhere. The Windows API is more dependable, less brittle, and it's also much simpler, easier to use, but much less portable. – Cheers and hth. - Alf Oct 01 '17 at 10:43
  • I know about recursion but don't know how to do it,Also I need it only for windows OS.I know I can make cross platform program using boost library but I need only for windows.Someone else must be needed the answer of my question because search system is also working like mine. – K.Rejepow Oct 01 '17 at 10:45
  • An alternative to recursion will be using a queue. When you find a folder, add it to the queue, and iterate the queue analysing all folders. – Andrei Damian Oct 01 '17 at 11:20

1 Answers1

2

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.

Daniel Sęk
  • 2,504
  • 1
  • 8
  • 17