By samoz


2009-03-04 19:35:58 8 Comments

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 within my program.

24 comments

@Shreevardhan 2016-05-28 02:41:34

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.

@PeterK 2016-07-11 08:03:49

AFAIK can also be used in C++14, but there it is still experimental: namespace fs = std::experimental::filesystem; . It seems to work ok though.

@green diod 2017-01-03 18:28:36

This should be the preferred answer for current use (starting with C++17)

@db_ 2017-01-03 18:50:27

Just be aware that current implementation of recursive_directory_iterator and _Directory_iterator skip through directories that it cannot open due to permission issues

@Roi Danton 2017-04-13 09:04:15

Heed when passing std::filesystem::path to std::cout, the quotation marks are included in the output. To avoid that, append .string() to the path to do an explicit instead of an implicit conversion (here std::cout << p.string() << std::endl;). Example: coliru.stacked-crooked.com/view?id=a55ea60bbd36a8a3

@anddero 2018-01-19 13:46:18

What about NON-ASCII characters in file names? Shouldn't std::wstring be used or what's the type from the iterator?

@Björn Larsson 2018-02-19 13:57:26

How do you place the file path in "p" into a string (or wstring)? All examples I've found cases errors when compiling with Visual Studio 2017. For example "error C2039: 'string': is not a member of 'std::experimental::filesystem::v1::directory_entry'" for "p.string()" and "error C3867: 'std::experimental::filesystem::v1::directory_entry::path': non-standard syntax; use '&' to create a pointer to member" for "wstring path = p.path;".

@Roi Danton 2018-07-19 15:50:10

@BjörnLarsson The example in my comment above is incomplete since the p inside the answer is the directory_iterator instead of the path (got confused by that since the term p is usually used for std::filesystem::path, sorry). p.path().string() for narrow strings respectively p.path().wstring() for wide strings should work.

@Roi Danton 2018-07-19 16:01:17

To correct myself again, p in the answer is the directory_entry.

@Brian R. Bondy 2009-03-04 19:38:49

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.

@Константин Ван 2016-08-11 00:47:19

Usage: FindFirstFile(TEXT("D:\\IMAGE\\MYDIRECTORY\\*"), &findFileData);

@Roi Danton 2017-04-13 07:51:02

With C++14 there is std::experimental::filesystem, with C++17 there is std::filesystem, which have similar functionality as boost (the libs are derived from boost). See answer of Shreevardhan below.

@FindOutIslamNow 2018-11-12 13:43:44

For windows, refer to docs.microsoft.com/en-us/windows/desktop/FileIO/… for details

@Peter Parker 2009-03-04 19:57:51

In small and simple tasks I do not use boost, I use dirent.h which is also available for windows:

DIR *dir;
struct dirent *ent;
if ((dir = opendir ("c:\\src\\")) != 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;
}

It is just a small header file and does most of the simple stuff you need without using a big template-based approach like boost(no offence, I like boost!).

The author of the windows compatibility layer is Toni Ronkko. In Unix, it is a standard header.

UPDATE 2017:

In C++17 there is now an official way to list files of your file system: std::filesystem. There is an excellent answer from Shreevardhan below with this source code:

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

@ArtOfWarfare 2013-05-18 23:19:00

I liked tinydir at this answer: stackoverflow.com/a/14679177/901641 I prefer more straight forward downloads (don't give me a list of choices, give me the right choice. Honestly, C/C++ already made navigating directories hard enough already; why would I want to screw around with that?)

@Peter Parker 2013-05-20 19:13:15

@ArtOfWarfare: tinydir was not even created when this question was answered. Also it is a wrapper around dirent (POSIX) and FindFirstFile (Windows) , while dirent.h just wraps dirent for windows. I think it is a personal taste, but dirent.h feels more as a standard

@ArtOfWarfare 2013-05-20 23:01:55

@Peter Parker - I just wanted to prop up that answer since it hasn't received as much attention yet and of the few here that I tried it was my favorite.

@Josh C 2014-09-24 14:04:28

Why doesn't this create a memory leak? I can understand closedir(dir) would clean *dir up, but what about *ent?

@Peter Parker 2014-09-25 11:41:57

@JoshC: because *ent is just a returned pointer of the internal representation. by closing the directory you will eliminate the *ent as well. As the *ent is only for reading, this is a sane design, i think.

@King Crimson 2015-04-29 04:25:21

Please note that readdir does NOT guarantee the order of the files being read. Refer to stackoverflow.com/questions/8977441/…

@Joe 2015-10-09 18:51:15

Not included in Windows by default, so this isn't very portable. stackoverflow.com/questions/5530933/…

@immibis 2015-11-22 08:15:42

@JoshC same reason fopen doesn't create a memory leak when paired with fclose.

@shinzou 2015-12-05 16:20:57

<dirent.h> doesn't exist on VS15.

@Martín Coll 2015-12-14 23:29:26

My two cents: I put this code into a C++ class here

@rustyx 2016-04-15 08:48:33

Don't waste your time - there is no <dirent.h>, opendir etc. in MSVC! I don't understand why people upvote this answer

@Peter Parker 2016-04-15 09:43:58

people get real!! this is a question from 2009 and it has not even mentioned VS. So do not criticize that your full proprietary (although quite nice) IDE is not supporting centuries old OS standards. Also my answer said it is "available" for windows, not "included" in any IDE from now and for all times ... I am pretty sure you can download dirent and put it in some include dir and voila there it is.

@Nic Hartley 2016-07-03 07:07:23

@rustyx Because it (a) provides a link to a compatibility layer for Windows (b) never once said that the solution worked out-of-the-box on all machines everywhere (c) works

@rustyx 2016-07-03 19:43:20

The answer is misleading. It should begin with: "...I use dirent.h, for which a Windows open-source compatibility layer also exists".

@ubisum 2016-09-24 15:11:07

it works, but if I display the names of files found in directory, I get "." and ".." in the list of files. why so? can I edit code to exclude these options? I need to iterate over list of files and this could be a problem

@FluorescentGreen5 2016-10-13 07:24:45

should have mentioned that it requires #include <dirent.h>, #include <stdio.h> and #include <stdlib.h>.

@STF 2017-03-27 04:30:04

I'm trying to include dirent.h but I got error - can't open source file

@Roi Danton 2017-04-13 07:49:52

With C++14 there is std::experimental::filesystem, with C++17 there is std::filesystem. See answer of Shreevardhan below. So no need for 3rd party libraries.

@Allen Hong 2017-08-02 10:22:35

it doesn't support the file path which is encoded with GBK.

@Wolfgang 2018-08-23 09:30:41

I think using the c++17 solution requires a std::cout << p.path().string() instead of std::cout << p?!

@K47 2018-11-16 17:12:39

How can I exclude "." and ".." (current and previous directory) from the result of method 1?

@Peter Parker 2018-11-20 12:54:05

just compare the strings..?

@Asadefa 2019-03-14 00:41:17

me too, thank you

@Asadefa 2019-03-14 00:42:04

thanks­­­­­­­­­­­­­­­­­­

@Kevin Ng 2018-09-29 10:54:16

Just something that I want to share and thank you for the reading material. Play around with the function for a bit to understand it. You may like it. e stood for extension, p is for path, and s is for path separator.

If the path is passed without ending separator, a separator will be appended to the path. For the extension, if an empty string is inputted then the function will return any file that does not have an extension in its name. If a single star was inputted than all files in the directory will be returned. If e length is greater than 0 but is not a single * then a dot will be prepended to e if e had not contained a dot at the zero position.

For a returning value. If a zero-length map is returned then nothing was found but the directory was open okay. If index 999 is available from the return value but the map size is only 1 then that meant there was a problem with opening the directory path.

Note that for efficiency, this function can be split into 3 smaller functions. On top of that, you can create a caller function that will detect which function it is going to call based on the input. Why is that more efficient? Said if you are going to grab everything that is a file, doing that method the subfunction that built for grabbing all the files will just grab all that are files and does not need to evaluate any other unnecessary condition everytime it found a file.

That would also apply to when you grab files that do not have an extension. A specific built function for that purpose would only evaluate for weather if the object found is a file and then whether or not if the name of the file has a dot in it.

The saving may not be much if you only read directories with not so much files. But if you are reading a mass amount of directory or if the directory has couple hundred thousands of files, it could be a huge saving.

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

@StarKiller4011 2018-09-25 13:10:15

I tried to follow the example given in both answers and it might be worth noting that it appears as though std::filesystem::directory_entry has been changed to not have an overload of the << operator. Instead of std::cout << p << std::endl; I had to use the following to be able to compile and get it working:

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

trying to pass p on its own to std::cout << resulted in a missing overload error.

@ZKR 2018-09-04 00:24:04

This answer should work for Windows users that have had trouble getting this working with Visual Studio with any of the other answers.

  1. Download the dirent.h file from the github page. But is better to just use the Raw dirent.h file and follow my steps below (it is how I got it to work).

    Github page for dirent.h for Windows: Github page for dirent.h

    Raw Dirent File: Raw dirent.h File

  2. Go to your project and Add a new Item (Ctrl+Shift+A). Add a header file (.h) and name it dirent.h.

  3. Paste the Raw dirent.h File code into your header.

  4. Include "dirent.h" in your code.

  5. Put the below void filefinder() method in your code and call it from your main function or edit the function how you want to use it.

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

@ducPham 2018-04-20 18:04:35

you can get all direct of files in your root directory by using std::experimental:: filesystem::directory_iterator(). Then, read the name of these pathfiles.

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

@tkingcer 2018-04-10 15:16:07

Since files and sub directories of a directory are generally stored in a tree structure, an intuitive way is to use DFS algorithm to recursively traverse each of them. Here is an example in windows operating system by using basic file functions in io.h. You can replace these functions in other platform. What I want to express is that the basic idea of DFS perfectly meets this problem.

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

@Venkat Vinay 2018-03-13 06:38:01

Shreevardhan answer works great. But if you want to use it in c++14 just make a change namespace fs = experimental::filesystem;

i.e.,

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

@congusbongus 2013-02-04 01:06:07

For a C only solution, please check this out. It only requires an extra header:

https://github.com/cxong/tinydir

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

Some advantages over other options:

  • It's portable - wraps POSIX dirent and Windows FindFirstFile
  • It uses readdir_r where available, which means it's (usually) threadsafe
  • Supports Windows UTF-16 via the same UNICODE macros
  • It is C90 so even very ancient compilers can use it

@ArtOfWarfare 2013-05-18 23:15:32

Very nice suggestion. I haven't tested it on a windows computer yet but it works brilliantly on OS X.

@Izzy 2016-07-08 11:43:06

works flawlessly on windows as well.

@Stepan Yakovenko 2017-10-18 09:20:05

The library doesn't support std::string, so you can't pass file.c_str() to the tinydir_open. It givers error C2664 during compilation on msvc 2015 in this case.

@Cesar Alejandro Montero Orozco 2017-06-28 05:23:35

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

    }

@ENHering 2017-05-22 04:44:07

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

@Shrikant 2013-10-23 06:36:15

I think, below snippet can be used to list all the files.

#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>

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

Following is the structure of the struct dirent

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

@selfboot 2019-04-28 09:25:56

I'd like this one.

@herohuyongtao 2013-12-30 20:56:40

One function is enough, you don't need to use any 3rd-party library (for Windows).

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

PS: as mentioned by @Sebastian, you could change *.* to *.ext in order to get only the EXT-files (i.e. of a specific type) in that directory.

@xandout 2014-01-15 20:29:43

Thanks for this, I implemented it here: gist.github.com/xandout/8443812

@kraxor 2014-05-29 13:14:15

This solution if platform-specific. That is the reason you need 3rd-party libraries.

@herohuyongtao 2014-05-29 14:13:11

@kraxor Yes, it only works in Windows, but OP never asks to have a cross-platform solution. BTW, I always prefer to choose something without using 3rd-libraries (if possible).

@kraxor 2014-05-29 17:20:49

@herohuyongtao OP never specified a platform, and giving a heavily platform-dependent solution to a generic question can be misleading. (What if there is a one-line solution that works only on PlayStation 3? Is that a good answer here?) I see you edited your answer to state that it only works on Windows, I guess it's fine this way.

@herohuyongtao 2014-05-29 17:23:22

@kraxor I think it should be a good answer if you can write it one line for a specific platform, but using the language OP indicates, i.e. C/C++.

@kraxor 2014-05-29 17:26:05

@herohuyongtao Well, I think a good answer is "there is no 'C/C++' solution, but here is how to do it on <platform>". Or something along those lines. Anyway, that's just me.

@Thomas 2014-09-18 21:20:51

@herohuyongtao OP mentioned he can't parse ls, meaning he is probably on unix.. anyway, good answer for Windows.

@Sebastian 2015-08-19 12:30:05

You should mention that the folder must end with a \ and if you only want some special files you could change . to e.g. *.dll and you get only the DLL-Files in that directory. Thats realy great but only on Windows ;-).

@herohuyongtao 2015-08-19 14:48:45

@Sebastian Thanks for the note and refined the answer accordingly.

@Joe 2015-10-09 18:53:06

The top accepted answer with <dirent.h> is also platform specific to *nix. I'm on windows, so this answer is more relevant to me, so +1. :-)

@shinzou 2015-12-05 16:30:44

Why sprintf and not a c++ function? Also, why not a deque instead of a vector for O(1) insertion?

@shinzou 2015-12-05 16:32:32

Also, how can you send it the current directory of the project?

@PerryC 2016-07-12 15:38:02

I ended up using a std::vector<std::wstring> and then fileName.c_str() instead of a vector of strings, which wouldn't compile.

@hshantanu 2017-04-16 21:13:29

Is there any way I can get multiple extensions? For an example *.exe and *.dll in the same path.

@bruce 2018-01-22 03:03:47

cool ! I only change [Character Set] of Visual Studio Project setting to "Not Set" , and it works well.

@Ferruccio 2018-03-29 20:39:28

The wildcard pattern *.* will retrieve all files with at least one dot in their filename. In Windows, the correct pattern to retrieve all files is simply *. MS-DOS required *.* to retrieve all files and it seems like the habit just stuck. Since most filenames tend to have a dot in them, this just fails silently on occasion and no-one notices.

@Krishnakumar CN 2018-09-06 13:24:47

In which order did this function return the filenames.? If no order is there any way to sort the names based on date as in Windows Explorer sort by date?

@Meekohi 2014-02-10 18:57:27

Why not use 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;
}

@sAguinaga 2015-07-08 17:41:25

works with C programming (tested it on Mac OS X)!

@Volomike 2016-05-15 00:46:03

This could be a better answer if you explain the required includes.

@orbitcowboy 2016-05-20 18:58:15

Test that glob() returns zero!

@Kemin Zhou 2016-07-21 17:35:07

This is good when you know the file you are looking for such as *.txt

@Bad 2015-06-25 16:51:30

Here is a very simple code in C++11 using boost::filesystem library to get file names in a directory (excluding folder names):

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

Output is like:

file1.txt
file2.dat

@Alexander Leon VI 2015-07-08 19:30:46

Hi, and where can I get this library?

@Bad 2015-07-08 20:02:38

@Alexander De Leon: You can get this library at their site boost.org, read getting started guide first, then use their boost::filesystem library boost.org/doc/libs/1_58_0/libs/filesystem/doc/index.htm

@Catalyst 2014-07-03 15:40:08

System call it!

system( "dir /b /s /a-d * > file_names.txt" );

Then just read the file.

EDIT: This answer should be considered a hack, but it really does work (albeit in a platform specific way) if you don't have access to more elegant solutions.

@YoYoYonnY 2015-04-26 15:37:02

I'm not allowed to execute the 'ls' command and parse the results from within my program. I knew there would be someone that would send something like this...

@Giacomo Marciani 2014-09-13 15:08:17

This implementation realizes your purpose, dynamically filling an array of strings with the content of the specified directory.

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

@Hal T 2017-02-21 15:17:11

How would I call this? I'm getting segfaults when I try to run this function on the first if block. I'm calling it with char **list; int numItems; exploreDirectory("/folder",list, numItems);

@Chris Redford 2014-07-11 17:15:55

I recommend using glob with this reusable wrapper. It generates a vector<string> corresponding to file paths that fit the glob pattern:

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

Which can then be called with a normal system wildcard pattern such as:

vector<string> files = globVector("./*");

@Camille Goudeseune 2015-05-21 16:51:14

Test that glob() returns zero.

@Tofuw 2016-02-23 10:36:03

I would like to use glob.h as you recommended. But still, I can't include the .h file : It says No such file or directory. Can you tell me how to solve this issue please ?

@Volomike 2016-05-15 17:16:46

Note that this routine goes only one level deep (no recursion). It also doesn't do a quick check to determine whether it's a file or directory, which you can do easily by switching GLOB_TILDE with GLOB_TILDE | GLOB_MARK and then checking for paths ending in a slash. You'll have to make either modification to it if you need that.

@Stepan Yakovenko 2017-10-18 09:09:55

no glob.h on msvc 2015

@Nikhil Augustine 2018-07-01 07:11:41

Is this cross-platform compatible?

@LmTinyToon 2018-10-05 11:30:56

Unfortunately you cannot find uniformly hidden files via glob.

@robertvarga 2011-04-08 16:48:01

Check out this class which uses the win32 api. Just construct an instance by providing the foldername from which you want the listing then call the getNextFile method to get the next filename from the directory. I think it needs windows.h and 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;
    }

};

@Homer6 2012-11-11 21:35:12

GNU Manual FTW

http://www.gnu.org/software/libc/manual/html_node/Simple-Directory-Lister.html#Simple-Directory-Lister

Also, sometimes it's good to go right to the source (pun intended). You can learn a lot by looking at the innards of some of the most common commands in Linux. I've set up a simple mirror of GNU's coreutils on github (for reading).

https://github.com/homer6/gnu_coreutils/blob/master/src/ls.c

Maybe this doesn't address Windows, but a number of cases of using Unix variants can be had by using these methods.

Hope that helps...

@JasonYen2205 2012-03-29 21:12:31

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

@Yas 2012-02-19 18:22:37

I hope this code help you.

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

@Daniel Kamil Kozar 2013-10-23 07:30:49

-1. string2wchar_t returns the address of a local variable. Also, you should probably use the conversion methods available in WinAPI instead of writing your own ones.

@Tim 2009-03-04 19:37:54

Try boost for x-platform method

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

or just use your OS specific file stuff.

@ice1000 2018-06-28 12:26:30

While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review

@Tim 2018-06-28 13:30:14

@ice1000 Seriously? This Q&A is from 2009

Related Questions

Sponsored Content

29 Answered Questions

[SOLVED] How can I add an empty directory to a Git repository?

  • 2008-09-22 16:41:03
  • Laurie Young
  • 819743 View
  • 3836 Score
  • 29 Answer
  • Tags:   git directory git-add

22 Answered Questions

[SOLVED] How do I list all files of a directory?

  • 2010-07-08 19:31:22
  • duhhunjonn
  • 3288638 View
  • 3475 Score
  • 22 Answer
  • Tags:   python directory

58 Answered Questions

[SOLVED] Get the source directory of a Bash script from within the script itself

  • 2008-09-12 20:39:56
  • Jiaaro
  • 1471851 View
  • 4428 Score
  • 58 Answer
  • Tags:   bash directory

10 Answered Questions

[SOLVED] Improve INSERT-per-second performance of SQLite?

42 Answered Questions

[SOLVED] How do I find all files containing specific text on Linux?

25 Answered Questions

[SOLVED] Listing only directories using ls in bash: An examination

  • 2013-01-16 06:07:00
  • Sibi
  • 733967 View
  • 835 Score
  • 25 Answer
  • Tags:   bash directory ls

14 Answered Questions

[SOLVED] How can I profile C++ code running on Linux?

  • 2008-12-17 20:29:24
  • Gabriel Isenberg
  • 466974 View
  • 1648 Score
  • 14 Answer
  • Tags:   c++ unix profiling

10 Answered Questions

16 Answered Questions

1 Answered Questions

[SOLVED] The Definitive C++ Book Guide and List

  • 2008-12-23 05:23:56
  • grepsedawk
  • 2148339 View
  • 4248 Score
  • 1 Answer
  • Tags:   c++ c++-faq

Sponsored Content