How can I get the list of files in a directory using C or C++?
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.
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 ("%sn", 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 (auto & p : fs::directory_iterator(path))
std::cout << p << std::endl;
}
Consider upvoting his answer, if you are using the C++17 approach.
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 %sn"), 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 %sn"),
FindFileData.cFileName);
FindClose(hFind);
}
}
Source code from the above msdn pages.
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 (auto & p : fs::directory_iterator(path))
std::cout << p << std::endl;
}
Also, std::filesystem::recursive_directory_iterator
can iterate the subdirectories as well.
上一篇: Apache CXF和Axis的区别