15

i need a way to search the computer for files like Windows Explorer. i want my program to search lets say hard drive c:. i need it to search C:\ for folders and files (just the ones you could see in c:\ then if the user clicks on a file on the list like the folder test (C:\test) it would search test and let the user see what files/folders are in it.

Jacob
  • 34,255
  • 14
  • 110
  • 165
blood
  • 746
  • 5
  • 13
  • 22

6 Answers6

18

Since you mentioned windows, the most straight forward winapi way to do it is with FindFirstFile and FindNextFile functions.

edit: Here's an example that shows you how to enumerate all files/folders in a directory.

#include <Windows.h>
#include <iostream>


int main()
{
    WIN32_FIND_DATA file;
    HANDLE search_handle=FindFirstFile(L"C:\\*",&file);
    if (search_handle)
    {
        do
        {
            std::wcout << file.cFileName << std::endl;
        }while(FindNextFile(search_handle,&file));
        FindClose(search_handle);

    }

}
monoceres
  • 4,722
  • 4
  • 38
  • 63
6

This will be OS dependent. The SO question

How can I get a list of files in a directory using C or C++?

handles this problem well. You can download DIRENT here.

Now that you have this, I'd recommend recursively searching for a file with a DFS/BFS algorithm. You can assume the whole directory structure is a tree where each file is a leaf node and each subdirectory is an internal node.

So all you have to do is,

  1. Get the list of files/folders in a directory with a function such as:
    void getFilesFolders(vector<string> & dir_list, const string & folder_name)
  2. If it's a directory, go to 1 with the directory name
  3. If it's a file, terminate if it's the file you're looking for, else move on to the next file.
Community
  • 1
  • 1
Jacob
  • 34,255
  • 14
  • 110
  • 165
  • How can I get a list of files in a directory using C or C++? is good but the code i can't get to work. only Brian R. Bondy's code the very last one of his but it only finds files part of what i wanted and also i can't find how it works so i can't edit it for my program :(. – blood Jul 29 '10 at 17:49
  • playing with dirent to see if it works get back to you on that – blood Jul 29 '10 at 17:55
  • uhh i can't get dirent i download it but it unzips as a .9 file and thats all. did i miss something because i just downloaded it from your link – blood Jul 29 '10 at 18:00
  • http://www.softagalleria.net/download/dirent/dirent-1.9.zip --- Maybe the .9.zip is confusing your unzip program. I can see a whole VC project here. – Jacob Jul 29 '10 at 18:21
  • The VC project at that link also has a demo file which prints the contents of a directory. – Jacob Jul 29 '10 at 18:31
2

You can use Directory class members to do this with C# or managed C++. See the following MSDN article:

http://support.microsoft.com/kb/307009

If you wish to use C++ with MFC you can use CFileFind

http://msdn.microsoft.com/en-us/library/f33e1618%28v=VS.80%29.aspx

You'll have to supply your own browse window to present the file system tree.

Or you can use one of the directory/file controls to do both for you.

Amardeep AC9MF
  • 18,464
  • 5
  • 40
  • 50
2

boost::filesystem can be a cross-platform solution for that (check out for such functions in it).

Ben Usman
  • 7,969
  • 6
  • 46
  • 66
  • 2
    i did not really want 3rd party software – blood Jul 29 '10 at 17:52
  • 1
    Not really 3rd party software so much, boost is virtually considered standard by C++ programmers, but then you don't seem to be one who likes using standard libraries (other than iostream, one of C++'s lesser great features). – CashCow Jan 15 '13 at 11:34
2
 #include <Windows.h>
#include <iostream>


int FindF(char* pDirectory)
{
    char szFindPath[MAX_PATH] = {0};
    strcpy(szFindPath, pDirectory);
    strcat(szFindPath, "\\*");
    WIN32_FIND_DATA file;
    HANDLE search_handle=FindFirstFile(szFindPath,&file);
    if (search_handle)
    {
        do
        {
            if(file.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
            {
              strcpy(szFindPath, pDirectory);
              strcat(szFindPath, "\\");
              strcat(szFindPath, file.cFileName);
              FindF(szFindPath);
            }
            std::wcout << file.cFileName << std::endl;
        }while(FindNextFile(search_handle,&file));
        CloseHandle(search_handle);

    }

}
Elixir Techne
  • 1,848
  • 15
  • 20
  • This is nearly a good solution other than: 1. It is mostly in C yet you put in iostream so you are writing in C with iostream... If you want to write in C++ I would at least use std::string. Your real serious blunder is you don't check for "dots" so yours will recurse forever (or more likely suffer from the name of this site). – CashCow Aug 19 '12 at 17:40
  • Use FindClose() to close handle, opened with FindFirstFile(). CloseHandle() will throw "invalid handle" in debug mode. – NoAngel Jul 27 '17 at 06:10
2

There really is no need to use 3rd party library to accomplish this. This is a short, independent function which lists all files (with their paths) in a directory, including subdiretories' files. std::string folderName has to finish with \, and if you want to list all files on computer, just create a loop in calling function along with GetLogicalDriveStrings (It returns strings with \, so it couldn't be more convenient in this case).

void FindAllFiles(std::string folderName)
{
    WIN32_FIND_DATA FileData;
    std::string folderNameWithSt = folderName + "*";
    HANDLE FirstFile = FindFirstFile(folderNameWithSt.c_str(), &FileData);

    if (FirstFile != INVALID_HANDLE_VALUE) {
        do {
            if (strcmp(FileData.cFileName, ".") != 0 && strcmp(FileData.cFileName, "..") != 0)
            {
                if(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                {
                    std::string NewPath = folderName + FileData.cFileName;
                    NewPath = NewPath + "\\";

                    FindAllFiles(NewPath);
                }
                else
                {
                    std::cout /*<< folderName*/ << FileData.cFileName << std::endl;
                }
            }
        } while(FindNextFile(FirstFile, &FileData));
    }
}

This is ASCII version, remember that files and folders can be named in Unicode

Brackets
  • 464
  • 7
  • 12
  • 1
    I'm just wondering, could you explain what are the benefits in comparison to FindFile, please? (and btw, shouldn't it be ASCII oder ANSI?) – Roi Danton Mar 02 '17 at 07:52