如何从我的C或c++代码中确定目录中的文件列表?

我不允许在程序中执行ls命令并解析结果。


当前回答

我试图遵循两个回答中给出的示例,可能值得注意的是,似乎std::filesystem::directory_entry已被更改为不重载<<操作符。而不是std::cout << p << std::endl;我必须使用以下能够编译并让它工作:

#include <iostream>
#include <filesystem>
#include <string>
namespace fs = std::filesystem;

int main() {
    std::string path = "/path/to/directory";
    for(const auto& p : fs::directory_iterator(path))
        std::cout << p.path() << std::endl;
}

试图将p单独传递给std::cout <<会导致丢失重载错误。

其他回答

不幸的是,c++标准并没有定义这样处理文件和文件夹的标准方法。

由于没有跨平台的方法,最好的跨平台方法是使用boost文件系统模块之类的库。

跨平台提升方法:

The following function, given a directory path and a file name, recursively searches the directory and its sub-directories for the file name, returning a bool, and if successful, the path to the file that was found. bool find_file(const path & dir_path, // in this directory, const std::string & file_name, // search for this name, path & path_found) // placing path here if found { if (!exists(dir_path)) return false; directory_iterator end_itr; // default construction yields past-the-end for (directory_iterator itr(dir_path); itr != end_itr; ++itr) { if (is_directory(itr->status())) { if (find_file(itr->path(), file_name, path_found)) return true; } else if (itr->leaf() == file_name) // see below { path_found = itr->path(); return true; } } return false; }

来源来自上面提到的boost页面。

对于Unix/Linux系统:

您可以使用opendir / readdir / closedir。

在目录中搜索条目“name”的示例代码如下: Len = strlen(name); Dirp = opendir("."); ((dp = readdir(dirp)) != NULL) 如果(dp - > d_namlen = = len & & !比较字符串(dp - > d_name,名字)){ (空白)closedir (dirp); 返回发现; } (空白)closedir (dirp); 返回NOT_FOUND;

来自上述手册页的源代码。

对于基于windows的系统:

你可以使用Win32 API的FindFirstFile / FindNextFile / FindClose函数。

The following C++ example shows you a minimal use of FindFirstFile. #include <windows.h> #include <tchar.h> #include <stdio.h> void _tmain(int argc, TCHAR *argv[]) { WIN32_FIND_DATA FindFileData; HANDLE hFind; if( argc != 2 ) { _tprintf(TEXT("Usage: %s [target_file]\n"), argv[0]); return; } _tprintf (TEXT("Target file is %s\n"), argv[1]); hFind = FindFirstFile(argv[1], &FindFileData); if (hFind == INVALID_HANDLE_VALUE) { printf ("FindFirstFile failed (%d)\n", GetLastError()); return; } else { _tprintf (TEXT("The first file found is %s\n"), FindFileData.cFileName); FindClose(hFind); } }

来自上述msdn页面的源代码。

尝试x平台方法

http://www.boost.org/doc/libs/1_38_0/libs/filesystem/doc/index.htm

或者只是使用特定于操作系统的文件。

由于目录下的文件和子目录一般存储在树状结构中,一种直观的方法是使用DFS算法递归遍历每个目录。 下面是一个在windows操作系统中使用io.h中的基本文件函数的例子。您可以在其他平台上替换这些功能。我想表达的是,DFS的基本思想完美地满足了这个问题。

#include<io.h>
#include<iostream.h>
#include<string>
using namespace std;

void TraverseFilesUsingDFS(const string& folder_path){
   _finddata_t file_info;
   string any_file_pattern = folder_path + "\\*";
   intptr_t handle = _findfirst(any_file_pattern.c_str(),&file_info);
   //If folder_path exsist, using any_file_pattern will find at least two files "." and "..", 
   //of which "." means current dir and ".." means parent dir
   if (handle == -1){
       cerr << "folder path not exist: " << folder_path << endl;
       exit(-1);
   }
   //iteratively check each file or sub_directory in current folder
   do{
       string file_name=file_info.name; //from char array to string
       //check whtether it is a sub direcotry or a file
       if (file_info.attrib & _A_SUBDIR){
            if (file_name != "." && file_name != ".."){
               string sub_folder_path = folder_path + "\\" + file_name;                
               TraverseFilesUsingDFS(sub_folder_path);
               cout << "a sub_folder path: " << sub_folder_path << endl;
            }
       }
       else
            cout << "file name: " << file_name << endl;
    } while (_findnext(handle, &file_info) == 0);
    //
    _findclose(handle);
}

为什么不使用glob()?

#include <glob.h>

glob_t glob_result;
glob("/your_directory/*",GLOB_TILDE,NULL,&glob_result);
for(unsigned int i=0; i<glob_result.gl_pathc; ++i){
  cout << glob_result.gl_pathv[i] << endl;
}

我希望这段代码对您有所帮助。

#include <windows.h>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

string wchar_t2string(const wchar_t *wchar)
{
    string str = "";
    int index = 0;
    while(wchar[index] != 0)
    {
        str += (char)wchar[index];
        ++index;
    }
    return str;
}

wchar_t *string2wchar_t(const string &str)
{
    wchar_t wchar[260];
    int index = 0;
    while(index < str.size())
    {
        wchar[index] = (wchar_t)str[index];
        ++index;
    }
    wchar[index] = 0;
    return wchar;
}

vector<string> listFilesInDirectory(string directoryName)
{
    WIN32_FIND_DATA FindFileData;
    wchar_t * FileName = string2wchar_t(directoryName);
    HANDLE hFind = FindFirstFile(FileName, &FindFileData);

    vector<string> listFileNames;
    listFileNames.push_back(wchar_t2string(FindFileData.cFileName));

    while (FindNextFile(hFind, &FindFileData))
        listFileNames.push_back(wchar_t2string(FindFileData.cFileName));

    return listFileNames;
}

void main()
{
    vector<string> listFiles;
    listFiles = listFilesInDirectory("C:\\*.txt");
    for each (string str in listFiles)
        cout << str << endl;
}