How can I get the list of files in a directory using C or C++?

前端 未结 27 3153
情书的邮戳
情书的邮戳 2020-11-21 05:30

How can I determine the list of files in a directory from inside my C or C++ code?

I\'m not allowed to execute the ls command and parse the results from

相关标签:
27条回答
  • 2020-11-21 06:12

    Try scandir() from dirent.h

    man scandir()

    0 讨论(0)
  • 2020-11-21 06:12

    This worked for me. It writes a file with just the names (no path) of all the files. Then it reads that txt file and prints it for you.

    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;
            }
    
        }
    
    0 讨论(0)
  • 2020-11-21 06:13

    C++17 now has a std::filesystem::directory_iterator, which can be used as

    #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;
    }
    

    Also, std::filesystem::recursive_directory_iterator can iterate the subdirectories as well.

    0 讨论(0)
  • 2020-11-21 06:13

    Unfortunately the C++ standard does not define a standard way of working with files and folders in this way.

    Since there is no cross platform way, the best cross platform way is to use a library such as the boost filesystem module.

    Cross platform boost method:

    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;
    }
    

    Source from the boost page mentioned above.

    For Unix/Linux based systems:

    You can use opendir / readdir / closedir.

    Sample code which searches a directory for entry ``name'' is:

    len = strlen(name);
    dirp = opendir(".");
    while ((dp = readdir(dirp)) != NULL)
            if (dp->d_namlen == len && !strcmp(dp->d_name, name)) {
                    (void)closedir(dirp);
                    return FOUND;
            }
    (void)closedir(dirp);
    return NOT_FOUND;
    

    Source code from the above man pages.

    For a windows based systems:

    You can use the Win32 API FindFirstFile / FindNextFile / FindClose functions.

    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);
       }
    }
    

    Source code from the above msdn pages.

    0 讨论(0)
  • 2020-11-21 06:13
    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;
    }
    
    0 讨论(0)
  • 2020-11-21 06:13

    This works for me. I'm sorry if I cannot remember the source. It is probably from a man page.

    #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/");
    }
    
    0 讨论(0)
提交回复
热议问题