【问题标题】:Reading all file names in a directory读取目录中的所有文件名
【发布时间】:2019-02-13 07:13:20
【问题描述】:

我正在尝试读取特定目录中存在的所有文件名。我用 C++ 编写了一个程序,但这只会直接在这个目录中打印文件。我想要子目录中也存在的所有文件。

我用 c++ 编写了一个程序,它打印目录中的文件名,但我也希望子目录中的所有文件名。

#include <stdio.h>
#include <windows.h>
#include <bits/stdc++.h>
#include <dirent.h>
using namespace std;

#include <sys/types.h>
#include <sys/stat.h>
#ifndef WIN32
#include <unistd.h>
#endif

#ifdef WIN32
#define stat _stat
#endif

int main ()
{
    DIR *dir;
    struct dirent *ent;
    if ((dir = opendir ("c:\\test")) != NULL) {
        /* print all the files and directories within directory */
        while ((ent = readdir (dir)) != NULL) {
            printf ("%s\n", ent->d_name);
        }
        closedir (dir);
    } else {
        /* could not open directory */
        perror ("");
        return EXIT_FAILURE;
    }
}

实际结果:1.直接打印目录下的文件名,打印子目录名。

预期:我希望程序不打印子目录名称,而是打印该子目录中的文件名。

【问题讨论】:

标签: c++ windows file


【解决方案1】:

如果您有可用的 C++17,请使用 recursive_directory_iterator。如果没有,您可以使用dirent.h-functions。例如,考虑以下通用traverseFiles-函数,它将找到的每个文件传递给处理检测到的文件的函数:

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

void traverseFiles(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[0] == '.') continue;

            if (f->d_type == DT_DIR)
                traverseFiles(path + f->d_name + "/", cb);

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


void fileDetected(const std::string &f) {
    std::cout << "file:" << f << std::endl;
}


int main() {
    traverseFiles("c:/somestartdir", &fileDetected);
}

【讨论】:

    【解决方案2】:

    使用 C++17 recursive_directory_iterator

    #include <filesystem>
    
    void ls_recursive(const std::filesystem::path& path) {
        for(const auto& p: std::filesystem::recursive_directory_iterator(path)) {
            std::cout << p.path() << '\n';
        }
    }
    

    【讨论】:

    • 嘿,谢谢亲爱的...但是我是编程新手,您能告诉我在函数中作为参数传递什么..
    • path。如果您使用的是不支持 C++17 的旧编译器,那么您的 dirent 方法是正确的。
    • 如果您的编译器不支持 C++17,您仍然可以使用 boost 搜索类似的解决方案 - 从长远来看,最好拥有跨平台代码并且不要将自己附加到 WinAPI。在 C++14 中,recursive_directory_iterator 将位于 experimental/filesystem
    【解决方案3】:

    如果您使用的是 Windows 操作系统,则可以运行以下代码以获取提供的目录中的文件列表。

    #include <windows.h>
    #include <TCHAR.h>
    #include <stdio.h>
    
    void Enum(TCHAR root[0xFF])
    {
        HANDLE hFind;
        WIN32_FIND_DATA wfd;
        TCHAR GeneralPath[0xFF];
        TCHAR AgainFolder[0xFF];
        TCHAR FileFullPath[0xFF];
    
        _stprintf(GeneralPath, _T("%s\\*.*"), root);
        hFind = FindFirstFile(GeneralPath, &wfd);
    
        if(INVALID_HANDLE_VALUE==hFind)
            return;
    
        do
        {
            if( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) //Checking Founded File Attribute is it File or Folder/Directory
            {
                if( !_tcscmp(wfd.cFileName, _T(".")) || !_tcscmp(wfd.cFileName, _T("..")) ) //if Founded directory is same(.) or parent(..) then ignore them
                    continue;
                _stprintf(AgainFolder, _T("%s\\%s"), root, wfd.cFileName);
                Enum(AgainFolder); //Recursion because folder is inside another folder
            }
            else
            {
                _stprintf(FileFullPath, _T("%s\\%s"), root, wfd.cFileName); //  "Folder\\fileName.extension"
                _tprintf(_T("%s\n"),FileFullPath); 
            }
    
        }while(FindNextFile(hFind, &wfd));
    
        CloseHandle(hFind);
        hFind=INVALID_HANDLE_VALUE;
    }
    int main()
    {
        TCHAR Folder[0xFF]=_T("c:\\windows");
        Enum(Folder);
        return 0;
    }
    

    如果您想访问完整的 Visual Studio 解决方案,您可以克隆 this 存储库。

    【讨论】:

    • 嘿,我想用 _T() 之类的字符串更改此参数 ...... string s="C:\\test" _T( s) 但这显示错误....有没有办法这样做...请帮助...
    • 您需要更改项目设置以使用字符集作为 ascii [项目属性 -> 配置属性 -> 常规 -> 字符集]
    • 然后将所有_T(s)替换为s
    猜你喜欢
    • 1970-01-01
    • 2013-12-02
    • 2018-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-07
    • 2014-11-10
    • 2013-02-28
    相关资源
    最近更新 更多