Home Upgrade Search Memberlist Extras Hacker Tools Award Goals Help Wiki Contact

C 

Recursively Display Contents In A Directory - Microsoft C++

- Microsoft C++
Should I just use Boost?

Tried using std::experimental::filesystem, it seems screwed.
Code
using namespace std;
namespace fs = std::experimental::filesystem;

The following code works, but does not search recursively
Code
#include <windows.h>
#include <tchar.h>
#include <shlobj.h>
#include <string.h>
#include <stdio.h>
#include <strsafe.h>
#pragma comment(lib, "User32.lib")
#include <iostream>
using namespace std;

void DisplayErrorBox(LPTSTR lpszFunction);

int _tmain(int argc, TCHAR* argv[])
{
    WIN32_FIND_DATA ffd;
    LARGE_INTEGER filesize;
    TCHAR szDir[MAX_PATH];
    HANDLE hFind = INVALID_HANDLE_VALUE;
    DWORD dwError = 0;
    TCHAR path[MAX_PATH];
    TCHAR subpath[MAX_PATH];

    // If the directory is not specified as a command-line argument,
    // print usage.
    if (SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, 0, path) != S_OK)
    {
        cout << "I could not retrieve the user's home directory!\n";
    }
    else
    {
    }


    // Prepare string for use with FindFile functions.  First, copy the
    // string to a buffer, then append '\*' to the directory name.

    StringCchCopy(szDir, MAX_PATH, path);
    StringCchCat(szDir, MAX_PATH, TEXT("\\*"));

    // Find the first file in the directory.

    hFind = FindFirstFile(szDir, &ffd);

    if (INVALID_HANDLE_VALUE == hFind)
    {
        _tprintf(TEXT("FindFirstFile"));
        return dwError;
    }

    // List all the files in the directory with some info about them.

    do
    {
        if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {

            filesize.LowPart = ffd.nFileSizeLow;
            filesize.HighPart = ffd.nFileSizeHigh;
            _tprintf(TEXT("  %s\\%s   +DIR \n"), path, ffd.cFileName);
        }
        else
        {
            filesize.LowPart = ffd.nFileSizeLow;
            filesize.HighPart = ffd.nFileSizeHigh;
            _tprintf(TEXT("  %s\\%s   \n"),path, ffd.cFileName);
        }
    } while (FindNextFile(hFind, &ffd) != 0);

    dwError = GetLastError();
    if (dwError != ERROR_NO_MORE_FILES)
    {
        _tprintf(TEXT("FindFirstFile"));
    }

    FindClose(hFind);
    return dwError;
}
Yeah that is not going to search recursively, because for recursion "you need to call yourself".

#include <string>
#include <functional>
#include <dirent.h>

void listFiles(const std::string &path, std::function<void(const std::string &)> cb) {
   if (auto dir = opendir(path.c_str())) {
       while (auto f = readdir(dir)) {
           if (!f->d_name || f->d_name[0] == '.') continue;
           if (f->d_type == DT_DIR)
               listFiles(path + f->d_name + "/", cb);

           if (f->d_type == DT_REG)
               cb(path + f->d_name);
       }
       closedir(dir);
   }
}

Call the above function from a main or _tmain with the following

listFiles("my_directory/", [](const std::string &path) {
   std::cout << path << std::endl;
});

This is c++11 standard.

Hope this helps
(Feb 2, 2020 08:45 AM)m1n0r1tyrep0rt Wrote:  Yeah that is not going to search recursively, because for recursion "you need to call yourself".

#include <string>
#include <functional>
#include <dirent.h>

void listFiles(const std::string &path, std::function<void(const std::string &)> cb) {
   if (auto dir = opendir(path.c_str())) {
       while (auto f = readdir(dir)) {
           if (!f->d_name || f->d_name[0] == '.') continue;
           if (f->d_type == DT_DIR)
               listFiles(path + f->d_name + "/", cb);

           if (f->d_type == DT_REG)
               cb(path + f->d_name);
       }
       closedir(dir);
   }
}

Call the above function from a main or _tmain with the following

listFiles("my_directory/", [](const std::string &path) {
   std::cout << path << std::endl;
});

This is c++11 standard.

Hope this helps

Thanks. I will look more into dirent.
give me a second pal and i will see if i can fix this for you :)
Pretty sure you want FindFirstFileW and FindNextFileW

code (vs2019 toolset v142)
Spoiler (Click to View)

output
Spoiler (Click to View)
(Feb 7, 2020 05:41 PM)SIM-3991524 Wrote:  Pretty sure you want FindFirstFileW and FindNextFileW

code (vs2019 toolset v142)
Spoiler (Click to View)

output
Spoiler (Click to View)

This worked great, thanks!
Just for the record another way to do this

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

using namespace boost::filesystem;

int main()
{
    path p = "C:\\Users\\gurlh\\Desktop";
    recursive_directory_iterator it{ p };
    while (it != recursive_directory_iterator{})
        std::cout << *it++ << '\n';
}
I'm an idiot.
I finally figured out how to use the filesystem library to search recursively. Switch from my default language of C++ 14 to C++17.
So without Boost, setting my Language to C++ 17. That was a headache.

Code
#include <filesystem>
#include <iostream>
#include <string>
#include <shlobj.h>
#include <KnownFolders.h>

namespace fs = std::filesystem;

int main() {
    PWSTR the_path;
    SHGetKnownFolderPath(FOLDERID_Desktop, KF_FLAG_DEFAULT, NULL, &the_path);
    fs::path current_dir(the_path);
  //  fs::path current_dir(".");
    // list all files containing an mp3 extension
    for (auto& file : fs::recursive_directory_iterator(current_dir)) {
        if (file.path().extension() == ".txt")
            std::cout << file.path().string() << file.path().filename().string() << std::endl;
    }
}


Possibly Related Threads...
Thread / Author Replies Views Last Post
by usa1010Nov 26, 2023 01:47 PM 5 239 Nov 26, 2023 01:47 PM
Last Post: Hackers
[Shell] by Cyber "Max" ShamanJan 25, 2022 08:56 PM 3 184 Jan 25, 2022 08:56 PM
Last Post: Cyber "Max" Shaman
[.NET] by unknown321Apr 17, 2020 02:09 PM 1 149 Apr 17, 2020 02:09 PM
Last Post: itcorp