Thomas Sampson

Listing files in a directory in C++

6 Comments

First of all I am not sure how you go about doing this in unix or linux! There is no standard, platform specific way to get all the files in a directory, however the following method works on windows making use of calls to winAPI so dont forget to include this!

#include <windows.h>

The following code then loops through a folder (in this case the starting folder of the executable) and puts the filenames into a string array.  The functions FindFirstFile and FindNextFile both work by populating a structure of the type WIN32_FIND_DATA which holds all the properties of the file in question.

UINT counter(0);
bool working(true);
string buffer;
string fileName[1000];

WIN32_FIND_DATA myimage;
HANDLE myHandle=FindFirstFile("*.jpg",&myimage);

if(myHandle!=INVALID_HANDLE_VALUE)
{
       buffer=myimage.cFileName;
       fileName[counter]=buffer;

       while(working)
       {
              FindNextFile(myHandle,&myimage);
              if(myimage.cFileName!=buffer)
              {
                     buffer=myimage.cFileName;
                     ++counter;
                     fileName[counter]=buffer;
              }
              else
              {
                      //end of files reached
                      working=false;
              }

       }
}

When the last file in the folder has been read, the FindNextFile method will keep returning the same filename over and over again in the while loop. To catch this i use a sort of swap buffer to check if the same filename is found twice, and if so exiting the loop. I am sure there is a better way to catch the last file and will look into this soon. If anyone knows a more efficient way to do this please let me know.

NOTE:- “*.jpg” could be replaced with “C:/myfolder” or “*.doc” or a combination of the two depending on how you wish to filter the files that are found.  Using “” would list all the files in the running directory of the executable.

Advertisements

Author: tomtech999

I have recently graduated with a 1st class degree in MComp Games Software Development at Sheffield Hallam University, focusing primarily on application development in C++, with experience in graphics programming, scripting languages, DVCS/VCS and web technology. In my spare time I enjoy Drumming, Reading and Snowboarding!

6 thoughts on “Listing files in a directory in C++

  1. FindNextFile() fails when the last file is reached. The following stores the names of all the files and folders in the current directory in a STL vector of strings.

    void listCurDir(std::vector& fnVec)
    {
    WIN32_FIND_DATA fd;
    HANDLE h = FindFirstFile(“*.*”, &fd);
    fnVec.clear();
    fnVec.push_back(fd.cFileName);
    while (FindNextFile(h, &fd))
    fnVec.push_back(fd.cFileName);
    }

  2. Seems to me you are doing this the hard way…

    Based on your code you could have used FindFirstFile to look directly for the filename…

    FindFirstFile(&buffer,&myimage)

    It would have found the first occurance of your file in the directory with no need to search every file looking for it.

  3. Please accept my gratitude!
    Your sweet code made my life easier!

  4. I’m using boost::file_system for a cross platform solution to this. I only mention this as you mention Linux in there. (And maybe because I dislike using but that’s another story 😉 )

    namespace fs = boost::file_system;

    void ClientPhysicsHandler::recurseResources(const std::string &path)
    {
    fs::path dir(path);
    fs::directory_iterator end_dir;
    for(fs::directory_iterator it(dir); it != end_dir; it++)
    {
    if(fs::is_directory(it->status()))
    recurseResources(it->path().directory_string());
    if(Util::endsWith(it->leaf(), “.hkx”))
    {
    loadResource(it->path().file_string());
    }
    }
    }

    This code recurses and performs an action on any file that matches a pattern. It can obviously be modified to do something else, such as search for files and return matches or the like.

  5. // I expanded on your efforts a bit, fixing the loop termination

    #include “stdafx.h”
    #include
    #include
    #include
    #include

    using namespace std;

    int main(int argc, char* argv[] ) {

    int nRetCode = 0;

    //WIN32 API method
    string buffer;
    vector fileNames;
    WIN32_FIND_DATA findFileData;
    HANDLE myHandle=FindFirstFile( “*.*”, &findFileData);

    if( myHandle != INVALID_HANDLE_VALUE) { //found at least one file
    buffer = findFileData.cFileName;
    fileNames.push_back( buffer);
    while( FindNextFile( myHandle, &findFileData) != 0) {
    buffer = findFileData.cFileName;
    fileNames.push_back( buffer);
    }
    }
    FindClose( myHandle);

    for( vector::iterator mj = fileNames.begin() ; mj != fileNames.end() ; mj++ ) {
    cout << *mj << endl;

    }

    return nRetCode;
    }

  6. bool working = TRUE; is not necessary.

    FileNextFile might return 0; if GetLastError() returns ERROR_NO_MORE_FILES, then that’s it.

    So.
    while(FindNextFile) {
    }

    will work