Krešimir Čulina
Krešimir Čulina

Reputation: 93

C++ Find all .wav files

I'm trying to create an application in C++ that would search all .wav files on the disk (including all subfolders and their subfolders and so on..., whole disk search, like antivirus search on Avast and similar) and store them in a string and save to a text file later on. I'm having troubles figuring out the way on how to actually do this and I could use some help.

This is what I done so far, it's only searching the C drive root folder and I don't know what to do now. I know I should use a loop of some sort but I don't know how to actually do it, there's no logical way that I can think to do it.

void finddata()
{
    MessageBox(NULL, "finddata called", "Started", MB_OK | MB_ICONINFORMATION);
    WIN32_FIND_DATA FindFileData; // A pointer to the WIN32_FIND_DATA structure that receives information about a found file or directory.
    HANDLE hFind; // Used to check the return value
    hFind = FindFirstFile("C://*.wav", &FindFileData);
    if(hFind == INVALID_HANDLE_VALUE)
    {
        MessageBox(NULL, "INVALID_HANDLE_VALUE", "Failed", MB_OK | MB_ICONINFORMATION);
    }
    else
    {
        string file;
        file = FindFileData.cFileName;
        file.append("|");
        MessageBox(NULL, file.c_str(), "YO", MB_OK | MB_ICONASTERISK); // string.c_str() to conv to LPCSTR
        FindClose(hFind);
    }
}

The MessageBox at the end is just there as a test, I'll remove it later on. I'm currently learning C++ and this is a sort of a beginner's project so I can get a hang of it.

Also, are there any limitations in size for the string data type? Thanks.

Upvotes: 2

Views: 2269

Answers (2)

Gauthier Boaglio
Gauthier Boaglio

Reputation: 10242

Recursivity is the way.

Here is a possible implementation (for inspiration, but do it your own way):

// Filtering by the given extension
void AppendFile(list<string>& fileList, const string& directory, const string& fileName, const string& extFilter)
{
    string fileExtension = fileName.substr(fileName.find_last_of(".") + 1);
    if (!fileExtension.empty())
    {
        // Extension doesn't match: return
        if (extFilter.find(fileExtension) == string::npos)
            return;
    }
    // If we have a match: append file to list
    fileList.push_back(directory + fileName);
}

// Getting the files of the given extension recursively (or not)
void GetFiles(list<string>& fileList, string directory, const string& extFilter, bool recursively = true)
{
    string filePath;

    directory += "\\";
    string filter = directory + "*";

    WIN32_FIND_DATA FindFileData;
    HANDLE hFind = FindFirstFile(filter.c_str(), &FindFileData);

    if (hFind == INVALID_HANDLE_VALUE) return;

    do
    {
        // If we find a (sub-)directory
        if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            // Here comes the recursive call
            if ((recursively) && (lstrcmp(FindFileData.cFileName, TEXT(".")) != 0) && (lstrcmp(FindFileData.cFileName, TEXT("..")) != 0))
                // The 'GetFiles()' calls itself on the sub-directory
                GetFiles(fileList, directory + FindFileData.cFileName, extFilter);
        }
        else
            // If we find a file: simply append it to the list
            AppendFile(fileList, directory, FindFileData.cFileName, extFilter);
    }
    while (FindNextFile(hFind, &FindFileData) != 0);

    FindClose(hFind);
}

Usage :

list<string> fileList;
GetFiles(fileList, "C:\\root_dir", "wav");

for(list<string>::iterator it = fileList.begin(); it != fileList.end(); ++it)
{
    cout << (*it) << endl;
}

Upvotes: 1

Mats Petersson
Mats Petersson

Reputation: 129314

Obviously, you do indeed need a FindNextFile call, and repeat that using a loop of some sort, until it returns a "no more files" return code.

To then search the entire disk, you will need to look for directories in the "current directory" (the root directory), and for every directory search into it - you can do that either by calling finddata recursively (adding the name of the directory as an argument to the function), or implement a stack in the code to track which directory you are in, and which one to "walk back to" for the next level.

I'm intentionally NOT writing the code for you, but describing what you need to do, since you are the one learning programming. I did this sort of thing in 1985 or so.

Upvotes: 2

Related Questions