Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用C或C+获取目录中的文件列表+;? 如何判断我的C或C++代码中目录中的文件列表?< /P>_C++_C_File_Directory - Fatal编程技术网

如何使用C或C+获取目录中的文件列表+;? 如何判断我的C或C++代码中目录中的文件列表?< /P>

如何使用C或C+获取目录中的文件列表+;? 如何判断我的C或C++代码中目录中的文件列表?< /P>,c++,c,file,directory,C++,C,File,Directory,我不允许执行ls命令并从程序中解析结果。请尝试boost for x-platform方法 或者只使用你的OS特定的文件。 < P>不幸的是,C++标准没有用这种方式定义文件和文件夹的标准方式。 由于没有跨平台的方式,最好的跨平台方式是使用库,例如 跨平台推进方法: 以下函数在给定目录路径和文件名的情况下,递归搜索目录及其子目录中的文件名,返回bool,如果成功,返回找到的文件的路径 bool find_file(const path & dir_path, // in

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

请尝试boost for x-platform方法


<>或者只使用你的OS特定的文件。

< P>不幸的是,C++标准没有用这种方式定义文件和文件夹的标准方式。 由于没有跨平台的方式,最好的跨平台方式是使用库,例如

跨平台推进方法:

以下函数在给定目录路径和文件名的情况下,递归搜索目录及其子目录中的文件名,返回bool,如果成功,返回找到的文件的路径

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的系统:

您可以使用//

在目录中搜索条目“name”的示例代码为:

来自上述手册页的源代码

对于基于windows的系统:

您可以使用Win32 API//函数

下面的C++示例显示了对FIFILSTSTFr../P>的最小使用

#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);
   }
}
#包括
#包括
#包括
void _tmain(int argc,TCHAR*argv[])
{
WIN32_FIND_DATA FindFileData;
处理高频风;
如果(argc!=2)
{
_tprintf(文本(“用法:%s[target_file]\n”),argv[0]);
返回;
}
_tprintf(文本(“目标文件是%s\n”),argv[1]);
hFind=FindFirstFile(argv[1],&FindFileData);
if(hFind==无效的句柄值)
{
printf(“FindFirstFile失败(%d)\n”,GetLastError());
返回;
} 
其他的
{
_tprintf(TEXT(“找到的第一个文件是%s\n”),
FindFileData.cFileName);
FindClose(hFind);
}
}

以上msdn页面的源代码。

2017年更新

在C++17中,现在有一种列出文件系统文件的正式方式:
std::filesystem
。下面的源代码给出了一个很好的答案:

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

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

它只是一个小的头文件,可以完成您需要的大部分简单工作,而无需使用基于大模板的方法,如boost(无意冒犯,我喜欢boost!)。

查看这个使用win32 api的类。只需通过提供要从中获取列表的
foldername
来构造一个实例,然后调用
getNextFile
方法从目录中获取下一个
filename
。我认为它需要
windows.h
stdio.h

class FileGetter{
    WIN32_FIND_DATAA found; 
    HANDLE hfind;
    char folderstar[255];       
    int chk;

public:
    FileGetter(char* folder){       
        sprintf(folderstar,"%s\\*.*",folder);
        hfind = FindFirstFileA(folderstar,&found);
        //skip .
        FindNextFileA(hfind,&found);        
    }

    int getNextFile(char* fname){
        //skips .. when called for the first time
        chk=FindNextFileA(hfind,&found);
        if (chk)
            strcpy(fname, found.cFileName);     
        return chk;
    }

};

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

#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;
}
#包括
#包括
#包括
#包括
使用名称空间std;
字符串wchar\u t2string(常量wchar\u t*wchar)
{
字符串str=“”;
int指数=0;
while(wchar[index]!=0)
{
str+=(char)wchar[index];
++指数;
}
返回str;
}
wchar_t*string2wchar_t(常量字符串和str)
{
wchar_t wchar[260];
int指数=0;
而(索引char**getKeys(char*data\u dir,char*tablename,int*num\u keys)
{
char**arr=malloc(每个表的最大记录数*sizeof(char*));
int i=0;
对于(;id_name);
}
*(num_keys)=i;
返回arr;
}
GNU手动FTW

此外,有时直接访问源代码(双关语)也很好。通过查看Linux中一些最常见命令的内部结构,您可以学到很多东西。我在github上设置了GNU的coreutils的简单镜像(用于阅读)

也许这不适用于Windows,但是使用这些方法可以有许多使用Unix变体的情况


希望对…有所帮助。

对于纯C解决方案,请检查此项。它只需要额外的标题:

与其他选项相比,有一些优势:

  • 它是可移植的-包装了POSIX dirent和Windows FindFirstFile
  • 它在可用的地方使用
    readdir\u r
    ,这意味着它(通常)是线程安全的
  • 通过相同的
    UNICODE
    宏支持Windows UTF-16
  • 它是C90,所以即使是非常古老的编译器也可以使用它

    • 我认为,下面的代码片段可以用来列出所有文件

      #include <stdio.h>
      #include <dirent.h>
      #include <sys/types.h>
      
      int main(int argc, char** argv) { 
          list_dir("myFolderName");
          return EXIT_SUCCESS;
      }  
      
      static void list_dir(const char *path) {
          struct dirent *entry;
          DIR *dir = opendir(path);
          if (dir == NULL) {
              return;
          }
      
          while ((entry = readdir(dir)) != NULL) {
              printf("%s\n",entry->d_name);
          }
      
          closedir(dir);
      }
      
      一个功能就足够了,您不需要使用任何第三方库(用于Windows)。

      #包括
      矢量获取\u文件夹(字符串文件夹)中的所有\u文件\u名称\u
      {
      载体名称;
      字符串搜索路径=文件夹+“/*.*”;
      WIN32_FIND_DATA fd;
      HANDLE hFind=::FindFirstFile(search_path.c_str(),&fd);
      如果(hFind!=无效的句柄值){
      做{
      //读取当前文件夹中的所有(真实)文件
      //,删除“!”读取其他2个默认文件夹。和。。
      if(!(fd.dwFileAttributes和文件属性目录)){
      名称。推回(fd.cFileName);
      }
      }while(::Fi)
      
      #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;
      }
      
      char **getKeys(char *data_dir, char* tablename, int *num_keys)
      {
          char** arr = malloc(MAX_RECORDS_PER_TABLE*sizeof(char*));
      int i = 0;
      for (;i < MAX_RECORDS_PER_TABLE; i++)
          arr[i] = malloc( (MAX_KEY_LEN+1) * sizeof(char) );  
      
      
      char *buf = (char *)malloc( (MAX_KEY_LEN+1)*sizeof(char) );
      snprintf(buf, MAX_KEY_LEN+1, "%s/%s", data_dir, tablename);
      
      DIR* tableDir = opendir(buf);
      struct dirent* getInfo;
      
      readdir(tableDir); // ignore '.'
      readdir(tableDir); // ignore '..'
      
      i = 0;
      while(1)
      {
      
      
          getInfo = readdir(tableDir);
          if (getInfo == 0)
              break;
          strcpy(arr[i++], getInfo->d_name);
      }
      *(num_keys) = i;
      return arr;
      }
      
      tinydir_dir dir;
      tinydir_open(&dir, "/path/to/dir");
      
      while (dir.has_next)
      {
          tinydir_file file;
          tinydir_readfile(&dir, &file);
      
          printf("%s", file.name);
          if (file.is_dir)
          {
              printf("/");
          }
          printf("\n");
      
          tinydir_next(&dir);
      }
      
      tinydir_close(&dir);
      
      #include <stdio.h>
      #include <dirent.h>
      #include <sys/types.h>
      
      int main(int argc, char** argv) { 
          list_dir("myFolderName");
          return EXIT_SUCCESS;
      }  
      
      static void list_dir(const char *path) {
          struct dirent *entry;
          DIR *dir = opendir(path);
          if (dir == NULL) {
              return;
          }
      
          while ((entry = readdir(dir)) != NULL) {
              printf("%s\n",entry->d_name);
          }
      
          closedir(dir);
      }
      
      struct dirent {
          ino_t d_ino; /* inode number */
          off_t d_off; /* offset to the next dirent */
          unsigned short d_reclen; /* length of this record */
          unsigned char d_type; /* type of file */
          char d_name[256]; /* filename */
      };
      
      #include <Windows.h>
      
      vector<string> get_all_files_names_within_folder(string folder)
      {
          vector<string> names;
          string search_path = folder + "/*.*";
          WIN32_FIND_DATA fd; 
          HANDLE hFind = ::FindFirstFile(search_path.c_str(), &fd); 
          if(hFind != INVALID_HANDLE_VALUE) { 
              do { 
                  // read all (real) files in current folder
                  // , delete '!' read other 2 default folder . and ..
                  if(! (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
                      names.push_back(fd.cFileName);
                  }
              }while(::FindNextFile(hFind, &fd)); 
              ::FindClose(hFind); 
          } 
          return names;
      }
      
      #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;
      }
      
      system( "dir /b /s /a-d * > file_names.txt" );
      
      #include <glob.h>
      #include <vector>
      using std::vector;
      
      vector<string> globVector(const string& pattern){
          glob_t glob_result;
          glob(pattern.c_str(),GLOB_TILDE,NULL,&glob_result);
          vector<string> files;
          for(unsigned int i=0;i<glob_result.gl_pathc;++i){
              files.push_back(string(glob_result.gl_pathv[i]));
          }
          globfree(&glob_result);
          return files;
      }
      
      vector<string> files = globVector("./*");
      
      int exploreDirectory(const char *dirpath, char ***list, int *numItems) {
          struct dirent **direntList;
          int i;
          errno = 0;
      
          if ((*numItems = scandir(dirpath, &direntList, NULL, alphasort)) == -1)
              return errno;
      
          if (!((*list) = malloc(sizeof(char *) * (*numItems)))) {
              fprintf(stderr, "Error in list allocation for file list: dirpath=%s.\n", dirpath);
              exit(EXIT_FAILURE);
          }
      
          for (i = 0; i < *numItems; i++) {
              (*list)[i] = stringDuplication(direntList[i]->d_name);
          }
      
          for (i = 0; i < *numItems; i++) {
              free(direntList[i]);
          }
      
          free(direntList);
      
          return 0;
      }
      
      #include <string>
      #include <iostream>
      #include <boost/filesystem.hpp>
      using namespace std;
      using namespace boost::filesystem;
      
      int main()
      {
          path p("D:/AnyFolder");
          for (auto i = directory_iterator(p); i != directory_iterator(); i++)
          {
              if (!is_directory(i->path())) //we eliminate directories
              {
                  cout << i->path().filename().string() << endl;
              }
              else
                  continue;
          }
      }
      
      file1.txt
      file2.dat
      
      #include <string>
      #include <iostream>
      #include <filesystem>
      namespace fs = std::filesystem;
      
      int main() {
          std::string path = "/path/to/directory";
          for (const auto & entry : fs::directory_iterator(path))
              std::cout << entry.path() << std::endl;
      }
      
      #include <ftw.h>
      
      int AnalizeDirectoryElement (const char *fpath, 
                                  const struct stat *sb,
                                  int tflag, 
                                  struct FTW *ftwbuf) {
      
        if (tflag == FTW_F) {
          std::string strFileName(fpath);
      
          DoSomethingWith(strFileName);
        }
        return 0; 
      }
      
      void WalkDirectoryTree (const char * pchFileName) {
      
        int nFlags = 0;
      
        if (nftw(pchFileName, AnalizeDirectoryElement, 20, nFlags) == -1) {
          perror("nftw");
        }
      }
      
      int main() {
        WalkDirectoryTree("some_dir/");
      }
      
      void DisplayFolderContent()
          {
      
              system("dir /n /b * > file_names.txt");
              char ch;
              std::fstream myStream("file_names.txt", std::fstream::in);
              while (myStream.get(ch))
              {
                  std::cout << ch;
              }
      
          }
      
      #include <string>
      #include <iostream>
      #include <filesystem>
      
      using namespace std;
      namespace fs = experimental::filesystem;
      
      int main()
      {
          string path = "C:\\splits\\";
          for (auto & p : fs::directory_iterator(path))
              cout << p << endl;
          int n;
          cin >> n;
      }
      
      #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);
      }
      
      #include <iostream>
      #include <filesystem>
      #include <string>
      #include <direct.h>
      using namespace std;
      namespace fs = std::experimental::filesystem;
      void ShowListFile(string path)
      {
      for(auto &p: fs::directory_iterator(path))  /*get directory */
           cout<<p.path().filename()<<endl;   // get file name
      }
      
      int main() {
      
      ShowListFile("C:/Users/dell/Pictures/Camera Roll/");
      getchar();
      return 0;
      }
      
      #include <stdio.h>
      #include <string.h>
      #include "dirent.h"
      
      string path = "C:/folder"; //Put a valid path here for folder
      
      void filefinder()
      {
          DIR *directory = opendir(path.c_str());
          struct dirent *direntStruct;
      
          if (directory != NULL) {
              while (direntStruct = readdir(directory)) {
                  printf("File Name: %s\n", direntStruct->d_name); //If you are using <stdio.h>
                  //std::cout << direntStruct->d_name << std::endl; //If you are using <iostream>
              }
          }
          closedir(directory);
      }
      
      #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;
      }
      
      #include <stdio.h>
      #include <sys/stat.h>
      #include <iostream>
      #include <dirent.h>
      #include <map>
      
      std::map<int, std::string> getFile(std::string p, std::string e = "", unsigned char s = '/'){
          if ( p.size() > 0 ){
              if (p.back() != s) p += s;
          }
          if ( e.size() > 0 ){
              if ( e.at(0) != '.' && !(e.size() == 1 && e.at(0) == '*') ) e = "." + e;
          }
      
          DIR *dir;
          struct dirent *ent;
          struct stat sb;
          std::map<int, std::string> r = {{999, "FAILED"}};
          std::string temp;
          int f = 0;
          bool fd;
      
          if ( (dir = opendir(p.c_str())) != NULL ){
              r.erase (999);
              while ((ent = readdir (dir)) != NULL){
                  temp = ent->d_name;
                  fd = temp.find(".") != std::string::npos? true : false;
                  temp = p + temp;
      
                  if (stat(temp.c_str(), &sb) == 0 && S_ISREG(sb.st_mode)){
                      if ( e.size() == 1 && e.at(0) == '*' ){
                          r[f] = temp;
                          f++;
                      } else {
                          if (e.size() == 0){
                              if ( fd == false ){
                                  r[f] = temp;
                                  f++;
                              }
                              continue;
                          }
      
                          if (e.size() > temp.size()) continue;
      
                          if ( temp.substr(temp.size() - e.size()) == e ){
                              r[f] = temp;
                              f++;
                          }
                      }
                  }
              }
      
              closedir(dir);
              return r;
          } else {
              return r;
          }
      }
      
      void printMap(auto &m){
          for (const auto &p : m) {
              std::cout << "m[" << p.first << "] = " << p.second << std::endl;
          }
      }
      
      int main(){
          std::map<int, std::string> k = getFile("./", "");
          printMap(k);
          return 0;
      }
      
      #include <string>
      #include <Windows.h>
      #include <vector>
      #include <locale>
      #include <codecvt>
      
      std::vector<std::string> listFilesInDir(std::string path)
      {
          std::vector<std::string> names;
          //Convert string to wstring
          std::wstring search_path = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(path);
          WIN32_FIND_DATA fd;
          HANDLE hFind = FindFirstFile(search_path.c_str(), &fd);
          if (hFind != INVALID_HANDLE_VALUE) 
          {
              do 
              {
                  // read all (real) files in current folder
                  // , delete '!' read other 2 default folder . and ..
                  if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 
                  {
                      //convert from wide char to narrow char array
                      char ch[260];
                      char DefChar = ' ';
                      WideCharToMultiByte(CP_ACP, 0, fd.cFileName, -1, ch, 260, &DefChar, NULL);
                      names.push_back(ch);
                  }
              } 
              while (::FindNextFile(hFind, &fd));
              ::FindClose(hFind);
          }
          return names;
      }
      
      #include<iostream>
      #include <dirent.h>
      using namespace std;
      char ROOT[]={'.'};
      
      void listfiles(char* path){
          DIR * dirp = opendir(path);
          dirent * dp;
          while ( (dp = readdir(dirp)) !=NULL ) {
               cout << dp->d_name << " size " << dp->d_reclen<<std::endl;
          }
          (void)closedir(dirp);
      }
      
      int main(int argc, char **argv)
      {
          char* path;
          if (argc>1) path=argv[1]; else path=ROOT;
      
          cout<<"list files in ["<<path<<"]"<<std::endl;
          listfiles(path);
      
          return 0;
      }
      
      #include <string>
      #include <iostream>
      #include <filesystem>
      namespace fs = std::filesystem;
      
      int main() {
          std::string path = "/path/to/directory";
          for (const auto & entry : fs::directory_iterator(path))
              std::cout << entry.path() << std::endl;
      }