How to Get the List of Files in a Directory Using C or C++

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

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

How to read data from all files in a directory using C Language?

The two most likely causes of the crash are not checking the return value of fopen – then either the fscanf or the fclose may crash when attempting to use entry_file when it's NULL – and the potential overflow of files.

Another problem which does not cause a crash is that the in_file->d_name does not contain the full path, but only the name of the file. So if you are testing the code inside /Users/tcn/data then it will appear to work, but it will fail elsewhere. Either prefix the filename with /Users/tcn/data/ or operate only on the current directory (.).

Fixes:

if ((entry_file = fopen(in_file->d_name, "r"))) {
(void) printf("%s\n", in_file->d_name);
if (fgets(files, sizeof files, entry_file)) { // or `while`?
// do something with `files`, it will be overwritten for next file
}
(void) fclose(entry_file);
}

And remove the other fclose(entry_file) from the end of the code.

Also note that if you use this code with an arbitrary directory, it might contain pipes and/or device nodes that will hang forever when you attempt to read them.

How can i read all files in directory in c++?

With std::filesystem you can do this:

std::string path_to_dir = '/some/path/';
for( const auto & entry : std::filesystem::directory_iterator( path_to_dir ) ){
std::cout << entry.path( ) << std::endl;
}

how to get list of all files in a directory and sub directories(full file path)

It is better to include what you have tried so far to solve your problem. That way we can help you debug your own code which can be very good for you.

However, C++17 made iterating over directories very easy through the directory iterator. Read more about the directory iterator here and see the code below:

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

Now second part of your question: you have entries paths, you can extract the file name out of it. Then, suppose you have two dictionaries one Russian and the other is Arabic. If you iterate over the filename character by character and check every time whether it is in the Russian dictionary or the Arabic one, you get the idea!

What you need to know is Arabic, Russian, whatever character has a Unicode code point (What's unicode?); meaning there is a unique value for it. Computers are good with 0s and 1s but not human readable characters (ASCII was made to solve this specific problem). If you are familiar with ASCII, you can consider Unicode as more inclusive character encoding standard. For instance see this page for Arabic characters encoding.

PS: Use hashtables implementations (instead of arrays) for your dictionary, since it has an amortized O(1) lookup.



Related Topics



Leave a reply



Submit