如何从我的C或c++代码中确定目录中的文件列表?
我不允许在程序中执行ls命令并解析结果。
如何从我的C或c++代码中确定目录中的文件列表?
我不允许在程序中执行ls命令并解析结果。
当前回答
尝试x平台方法
http://www.boost.org/doc/libs/1_38_0/libs/filesystem/doc/index.htm
或者只是使用特定于操作系统的文件。
其他回答
为什么不使用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;
}
我认为,下面的代码片段可以用来列出所有的文件。
#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
int main(int argc, char** argv) {
list_dir("myFolderName");
return EXIT_SUCCESS;
}
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);
}
这是使用的结构(出现在direct .h中):
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 */
};
基于上面的答案
#include <vector>
#include <string>
#include <algorithm>
#ifdef _WIN32
#include <windows.h>
std::vector<std::string> files_in_directory(std::string path)
{
std::vector<std::string> files;
// check directory exists
char fullpath[MAX_PATH];
GetFullPathName(path.c_str(), MAX_PATH, fullpath, 0);
std::string fp(fullpath);
if (GetFileAttributes(fp.c_str()) != FILE_ATTRIBUTE_DIRECTORY)
return files;
// get file names
WIN32_FIND_DATA findfiledata;
HANDLE hFind = FindFirstFile((LPCSTR)(fp + "\\*").c_str(), &findfiledata);
if (hFind != INVALID_HANDLE_VALUE)
{
do
{
files.push_back(findfiledata.cFileName);
}
while (FindNextFile(hFind, &findfiledata));
FindClose(hFind);
}
// delete current and parent directories
files.erase(std::find(files.begin(), files.end(), "."));
files.erase(std::find(files.begin(), files.end(), ".."));
// sort in alphabetical order
std::sort(files.begin(), files.end());
return files;
}
#else
#include <dirent.h>
std::vector<std::string> files_in_directory(std::string directory)
{
std::vector<std::string> files;
// open directory
DIR *dir;
dir = opendir(directory.c_str());
if (dir == NULL)
return files;
// get file names
struct dirent *ent;
while ((ent = readdir(dir)) != NULL)
files.push_back(ent->d_name);
closedir(dir);
// delete current and parent directories
files.erase(std::find(files.begin(), files.end(), "."));
files.erase(std::find(files.begin(), files.end(), ".."));
// sort in alphabetical order
std::sort(files.begin(), files.end());
return files;
}
#endif // _WIN32
2017年更新:
在c++ 17中,现在有一种官方的方法来列出文件系统中的文件:std::filesystem。下面是Shreevardhan给出的一个很好的答案:
# include <字符串> # include < iostream > # include <文件> 命名空间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; }
旧的回答:
在小而简单的任务中,我不使用boost,我使用direct .h。它可以作为UNIX中的标准标头使用,也可以通过Toni Ronkko创建的兼容层用于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;
}
它只是一个小的头文件,做了大部分你需要的简单的事情,而不使用像boost这样的基于模板的大方法(无意冒犯,我喜欢boost!)
由于目录下的文件和子目录一般存储在树状结构中,一种直观的方法是使用DFS算法递归遍历每个目录。 下面是一个在windows操作系统中使用io.h中的基本文件函数的例子。您可以在其他平台上替换这些功能。我想表达的是,DFS的基本思想完美地满足了这个问题。
#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);
}