How to Get a List of Files in a Directory in C++

How to list all files of a directory recursively in c

I can't for the life of me think why anybody would want to enumerate directories by calling main() recursively. But, since I can't resist a pointless challenge, here's a version that does. Do I get the prize for "most fruitless waste of ten minutes?" ;)

#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
#include <stdlib.h>

int main (int argc, char **argv)
{
const char *path;
if (argc != 2) path = "/etc"; /* Set starting directory, if not passed */
else
path = argv[1];

DIR *dir = opendir (path);
if (dir)
{
struct dirent *dp;
while ((dp = readdir(dir)) != NULL)
{
if (dp->d_name[0] != '.')
{
char *fullpath = malloc (strlen (path) + strlen (dp->d_name) + 2);
strcpy (fullpath, path);
strcat (fullpath, "/");
strcat (fullpath, dp->d_name);
if (dp->d_type == DT_DIR)
{
char **new_argv = malloc (2 * sizeof (char *));
new_argv[0] = argv[0];
new_argv[1] = fullpath;
main (2, new_argv);
free (new_argv);
}
else
printf ("%s\n", fullpath);
free (fullpath);
}
}
closedir(dir);
}
else
fprintf (stderr, "Can't open dir %s: %s", path, strerror (errno));
return 0;
}

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

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

Old Answer:

In small and simple tasks I do not use boost, I use dirent.h. It is available as a standard header in UNIX, and also available for Windows via a compatibility layer created by Toni Ronkko.

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!).

C: Store a list of files in a directory into an array

It is because you are not allocating memory for your filesList individual elements. You are assisgning it the "dir->d_name" (basically pointing each element of your filesList to a single d_name). You should be doing a malloc for each entry in there.

else {
filesList[i] = (char*) malloc (strlen(dir->d_name)+1);
strncpy (filesList[i],dir->d_name, strlen(dir->d_name) );
i++;
}

Listing directory contents using C and Windows

Just like everyone else said (with FindFirstFile, FindNextFile and FindClose)... but with recursion!

bool ListDirectoryContents(const char *sDir)
{
WIN32_FIND_DATA fdFile;
HANDLE hFind = NULL;

char sPath[2048];

//Specify a file mask. *.* = We want everything!
sprintf(sPath, "%s\\*.*", sDir);

if((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE)
{
printf("Path not found: [%s]\n", sDir);
return false;
}

do
{
//Find first file will always return "."
// and ".." as the first two directories.
if(strcmp(fdFile.cFileName, ".") != 0
&& strcmp(fdFile.cFileName, "..") != 0)
{
//Build up our file path using the passed in
// [sDir] and the file/foldername we just found:
sprintf(sPath, "%s\\%s", sDir, fdFile.cFileName);

//Is the entity a File or Folder?
if(fdFile.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)
{
printf("Directory: %s\n", sPath);
ListDirectoryContents(sPath); //Recursion, I love it!
}
else{
printf("File: %s\n", sPath);
}
}
}
while(FindNextFile(hFind, &fdFile)); //Find the next file.

FindClose(hFind); //Always, Always, clean things up!

return true;
}

ListDirectoryContents("C:\\Windows\\");

And now its UNICODE counterpart:

bool ListDirectoryContents(const wchar_t *sDir)
{
WIN32_FIND_DATA fdFile;
HANDLE hFind = NULL;

wchar_t sPath[2048];

//Specify a file mask. *.* = We want everything!
wsprintf(sPath, L"%s\\*.*", sDir);

if((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE)
{
wprintf(L"Path not found: [%s]\n", sDir);
return false;
}

do
{
//Find first file will always return "."
// and ".." as the first two directories.
if(wcscmp(fdFile.cFileName, L".") != 0
&& wcscmp(fdFile.cFileName, L"..") != 0)
{
//Build up our file path using the passed in
// [sDir] and the file/foldername we just found:
wsprintf(sPath, L"%s\\%s", sDir, fdFile.cFileName);

//Is the entity a File or Folder?
if(fdFile.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)
{
wprintf(L"Directory: %s\n", sPath);
ListDirectoryContents(sPath); //Recursion, I love it!
}
else{
wprintf(L"File: %s\n", sPath);
}
}
}
while(FindNextFile(hFind, &fdFile)); //Find the next file.

FindClose(hFind); //Always, Always, clean things up!

return true;
}

ListDirectoryContents(L"C:\\Windows\\");

C++: Get and list all the files from directory that user writes

I would use std::filesystem::directory_iterator to go through all files in a given directory.

#include <iostream>
#include <filesystem>

int main()
{
const std::filesystem::path path{ "C:\\temp" };
for (auto const& dir_entry : std::filesystem::directory_iterator{ path })
std::cout << dir_entry << '\n';
}

To get the filename only (without the path), use:

    std::cout << dir_entry.path().filename() << '\n';


Related Topics



Leave a reply



Submit