如何从我的C或c++代码中确定目录中的文件列表?
我不允许在程序中执行ls命令并解析结果。
如何从我的C或c++代码中确定目录中的文件列表?
我不允许在程序中执行ls命令并解析结果。
当前回答
这个答案应该适用于Windows用户在使用Visual Studio和任何其他答案时遇到的问题。
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 Go to your project and Add a new Item (Ctrl+Shift+A). Add a header file (.h) and name it dirent.h. Paste the Raw dirent.h File code into your header. Include "dirent.h" in your code. 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); }
其他回答
对于C的唯一解决方案,请检查这个。它只需要一个额外的头文件:
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);
与其他选项相比,以下是一些优势:
它是可移植的-包装POSIX的dirent和Windows的FindFirstFile 它在可用的地方使用readdir_r,这意味着它(通常)是线程安全的 通过相同的UNICODE宏支持Windows UTF-16 它是C90,所以即使是非常古老的编译器也可以使用它
根据herohuyongtao的帖子和其他一些帖子:
http://www.cplusplus.com/forum/general/39766/
FindFirstFile的预期输入类型是什么?
如何将wstring转换为字符串?
这是一个Windows解决方案。
因为我想要传入std::string并返回一个字符串向量,所以我必须进行一些转换。
#include <string>
#include <Windows.h>
#include <vector>
#include <locale>
#include <codecvt>
std::vector<std::string> listFilesInDir(std::string path)
{
std::vector<std::string> names;
//Convert string to wstring
std::wstring search_path = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(path);
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))
{
//convert from wide char to narrow char array
char ch[260];
char DefChar = ' ';
WideCharToMultiByte(CP_ACP, 0, fd.cFileName, -1, ch, 260, &DefChar, NULL);
names.push_back(ch);
}
}
while (::FindNextFile(hFind, &fd));
::FindClose(hFind);
}
return names;
}
尝试x平台方法
http://www.boost.org/doc/libs/1_38_0/libs/filesystem/doc/index.htm
或者只是使用特定于操作系统的文件。
Shreevardhan的设计也适用于遍历子目录:
#include <string>
#include <iostream>
#include <filesystem>
using namespace std;
namespace fs = filesystem;
int main()
{
string path = "\\path\\to\\directory";
// string path = "/path/to/directory";
for (auto & p : fs::recursive_directory_iterator(path))
cout << p.path() << endl;
}
编译:cl /EHsc /W4 /WX /std:c++17 ListFiles.cpp
我希望这段代码对您有所帮助。
#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;
}