算法一:使用 _finddata_t

#include <io.H>
#include <string>
#include <deque>
//注意,本算法使用filter(fileType)只能遍历目标文件夹folderPath下的对应类型文件
void dfsFolder(std::string folderPath, std::deque<std::string> & filenames, std::string fileType = "")
{
    _finddata_t   FileInfo;
    if (*folderPath.rbegin() != '\\')//检查原始文件夹名称是否以'\\'结尾
    {
        folderPath += "\\";
    }
    if (fileType == "")//如果filter不启用
    {
        fileType = "*.*";
    }
    else if (fileType == "*.*" || fileType == "*")//无需操作、主要在回调本函数时使用
    {
    }
    else
    {
        fileType = "*." + fileType;
    }
    std::string fileFindPath = folderPath + fileType;

    std::cout << "当前的查找目录为" << fileFindPath << std::endl;

    long  Handle = _findfirst(fileFindPath.c_str(), &FileInfo);

    if (Handle == -1L)
    {
        std::cerr << "can not match the folder path" << std::endl;
        //exit(-1);
        return ;
    }
    do {
        //判断是否有子目录  
        if (FileInfo.attrib & _A_SUBDIR)
        {
            //这个语句很重要  
            if ((strcmp(FileInfo.name, ".") != 0) && (strcmp(FileInfo.name, "..") != 0))
            {
                std::string newPath = folderPath + FileInfo.name;
                dfsFolder(newPath, filenames, fileType);
            }
        }
        else
        {
            std::string newPath = folderPath + FileInfo.name;
            filenames.push_back(newPath);
            std::cout << newPath.c_str() << std::endl;
        }
    } while (_findnext(Handle, &FileInfo) == 0);

    _findclose(Handle);
}
int main()
{
    std::deque<string> ddd;
    dfsFolder("D:", ddd, "jpg");//
    system("pause");
    return 0;
}

算法二:使用 _finddata_t

#include <io.H>
#include <string>
#include <deque>
//可遍历出子文件里的对应文件,可用filter进行文件后缀的过滤
int listAllFile(std::string path, std::deque<std::string> & dstFilePathList, std::string fileTypeFilter = "")
{
    _finddata_t   FileInfo;
    bool needFilter = false;
    std::string fileFindPath;
    if (*path.rbegin() != '\\')
    {
        path += "\\";
    }
    else
    {

    }
    fileFindPath = path + "*.*";
    if (fileTypeFilter == "" || fileTypeFilter == "*.*" || fileTypeFilter == "*")
    {
        needFilter = false;
    }
    else
    {
        needFilter = true;
    }

    std::cout << "当前的查找目录为" << fileFindPath << std::endl;

    long  Handle = _findfirst(fileFindPath.c_str(), &FileInfo);

    if (Handle == -1L)
    {
        std::cerr << "can not match the folder path" << std::endl;
        //exit(-1);
        return -1;//空文件件
    }
    do {
        //判断是否有子目录  
        if (FileInfo.attrib & _A_SUBDIR)
        {
            //这个语句很重要  
            if ((strcmp(FileInfo.name, ".") != 0) && (strcmp(FileInfo.name, "..") != 0))
            {
                std::string newPath = path + FileInfo.name;
                listAllFile(newPath, dstFilePathList, fileTypeFilter);
            }
        }
        else
        {
            if (needFilter != true)//如果不需要进行文件类型过滤
            {
                std::string newPath = path + FileInfo.name;
                dstFilePathList.push_back(newPath);
                std::cout << newPath.c_str() << std::endl;
            }
            else if (needFilter == true && std::string(FileInfo.name).find(fileTypeFilter) != -1)//如果需要文件类型过滤,并且本文件类型对应正确
            {
                std::string newPath = path + FileInfo.name;
                dstFilePathList.push_back(newPath);
                std::cout << newPath.c_str() << std::endl;
            }
            else
            {
                std::cout << "文件" << FileInfo.name << "与NameFilter=" << fileTypeFilter << "不符,故不加入对应目标文件夹列表" << std::endl;
            }
        }
    } while (_findnext(Handle, &FileInfo) == 0);

    _findclose(Handle);
    return dstFilePathList.size();//返回对应文件列表的大小
}
int main()
{
    std::deque<string> ddd;
    dfsFolder("D:", ddd, "jpg");//
    system("pause");
    return 0;
}

算法三:使用CFileFind(MFC环境下)

//没有用filter
int listAllFile(const CString & path, std::deque<std::string> & FilePathList)
{
    CFileFind stFileFind;
    CString FileFindPath;
    if (path.Right(1) != '\\')
    {
        FileFindPath = path + "\\*";
    }
    else
    {
        FileFindPath = path + "*";
    }
    bool fResult = stFileFind.FindFile(FileFindPath);
    if (false == fResult)
    {
        PrintSysLog("空文件夹,请重新选择");
        return -1;//空文件夹
    }

    while (TRUE == fResult)
    {
        fResult = stFileFind.FindNextFile();
        //过滤掉“.”和“..”
        if (TRUE == stFileFind.IsDots())continue;
        else if (TRUE == stFileFind.IsDirectory())//如果是文件夹,则递归获取文件
        {
            if (false == listAllFile(stFileFind.GetFilePath(), FilePathList))//递归
                return FALSE;
        }
        else
        {
            CString strFileName = stFileFind.GetFilePath();
            //查找自己需要的文件类型,继续做其他操作。
            if (stFileFind.IsArchived())//档案(正常文件) 、可尝试自己加filter
            {
                FilePathList.push_back(strFileName.GetBuffer());//将文件夹的地址放入其中
            }
            else if (stFileFind.IsCompressed())//压缩
            {
                //MessageBox("Compressed");
            }
            else if (stFileFind.IsDirectory())//目录
            {
                //MessageBox("Directory");
            }
            else if (stFileFind.IsSystem())//系统
            {
                //MessageBox("System");
            }
            else if (stFileFind.IsHidden())//隐藏
            {
                //MessageBox("Hidden");
            }
            else if (stFileFind.IsTemporary())//临时
            {
                //MessageBox("Temporary");
            }
            else if (stFileFind.IsNormal())//常规
            {
                //MessageBox(strFileName);
            }
            else if (stFileFind.IsReadOnly())//只读
            {
                //MessageBox(strFileName);
            }
            else
            {
                //MessageBox(strFileName);
            }
        }
    }
    stFileFind.Close();
    std::ostringstream tempStr;
    tempStr << "获取到的文件有" << "\r\n";
    for (auto listPos = FilePathList.begin(); listPos != FilePathList.end(); listPos++)
    {
        tempStr << *listPos << "\r\n";
    }
    PrintSysLog(tempStr.str());
    return 0;
}