C++目录树数据转换为矢量

C++ directory tree data into vector

本文关键字:转换 目录树 数据 C++      更新时间:2023-10-16

我可以使用Windows APIFindFirstFile+FindNextFile遍历指定的目录及其所有子目录,并将所有目录名和文件名存储在类似的结构上吗

typedef struct node_t
{
vector <wstring *> val;
vector <node_t *> subnodes;
node_t* parent;
}*pnode, node;

val表示指定目录上的文件名。subnodes表示指定目录上的子目录。parent表示指向父节点的指针。

因为这是一个非常小的项目,我正在建设。如果没有必要,我不想使用第三方库。

编辑

这是我的密码。结果CCD_ 6全局向量变量的层次结构结果与我的目录结构不同。你能指出不正确的代码吗?

#include <string>
#include <iostream>
#include <vector>
#include <windows.h>
#include <tchar.h>
using namespace std;
typedef struct node_t
{
vector <wstring> val;
vector <node_t *> subnodes;
node_t* parent;
}*pnode, node;
node* nd;
pnode ndparent = NULL;

void log(LPCTSTR lpRecordStr, ...)
{
TCHAR       tszLogFile[MAX_PATH]        = {0};
TCHAR       pInfo[1024]                 = {0};
HRESULT     hr                          = S_FALSE;
TCHAR       szProgramDataPath[MAX_PATH] = {0};
BOOL        bExists                     = TRUE;
do 
{
SYSTEMTIME LocalTime ;
GetLocalTime(&LocalTime);
_stprintf_s(pInfo,_T("[test] [%04d-%02d-%02d,%02d:%02d:%02d:%03d]"),
LocalTime.wYear,
LocalTime.wMonth,
LocalTime.wDay,
LocalTime.wHour, 
LocalTime.wMinute,
LocalTime.wSecond,
LocalTime.wMilliseconds
);
va_list argList;
va_start(argList, lpRecordStr);
_vsntprintf_s(pInfo + _tcslen(pInfo) , 1024 - _tcslen(pInfo) - 1 , 1024, lpRecordStr, argList);
va_end(argList);
_tcscat_s(pInfo , _T("n"));
OutputDebugString(pInfo);

} while (FALSE);

}
VOID SearchFile(TCHAR *Path, pnode pnd)
{
HANDLE                  hFind;
WIN32_FIND_DATA         wfd;
TCHAR                   tszPathTemp[512]        =   {0};
TCHAR                   tszParam[512]       =   {0};
ZeroMemory(&wfd,sizeof(WIN32_FIND_DATA));
memset(tszPathTemp,0,sizeof(tszPathTemp));
_stprintf_s(tszPathTemp, MAX_PATH, _T("%s\*.*"),Path);
hFind=FindFirstFile(tszPathTemp,&wfd);
if(INVALID_HANDLE_VALUE==hFind)
{
return;
}
do
{
if(_tcscmp(wfd.cFileName,_T("."))==0|| _tcscmp(wfd.cFileName,_T(".."))==0 )
{
continue;
}
if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
_stprintf_s(tszPathTemp, MAX_PATH, _T("%s\%s"),Path,wfd.cFileName);
log(_T("dir: %s"), tszPathTemp);
nd->subnodes.push_back(new node());
ndparent = nd;
nd = nd->subnodes[nd->subnodes.size()-1];
nd->val.push_back(wstring(wfd.cFileName));
nd->parent = ndparent;
SearchFile(tszPathTemp, nd);
}
else
{
_stprintf_s(tszPathTemp, MAX_PATH, _T("%s\%s"),Path, wfd.cFileName);
log(_T("dir: %s, filename:%s"), tszPathTemp, wfd.cFileName);
nd->val.push_back(wstring(wfd.cFileName));
}
}while(FindNextFile(hFind,&wfd));
FindClose(hFind);
}
int main()
{
vector<wstring> file;
nd = new node();
nd->parent = ndparent;
SearchFile(_T("Y:"), nd);
while(nd->parent != NULL)
{
nd = nd->parent;
}
}

这里有一个递归函数,用于查找所有文件和子文件夹,然后将它们放在一个数组中:

void files_and_folders(vector<wstring> &sa, wstring dir)
{
if (!dir.size()) return;
if (dir[dir.size() - 1] != L'') dir += L"\";
WIN32_FIND_DATA find = { 0 };
wstring wildcard = dir + L"*";
HANDLE hfind = FindFirstFile(wildcard.c_str(), &find);
if (hfind == INVALID_HANDLE_VALUE)
return;
do
{
if (wcscmp(find.cFileName, L".") == 0 || wcscmp(find.cFileName, L"..") == 0)
continue;
wstring path = dir + find.cFileName;
sa.push_back(path);
if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
files_and_folders(sa, path);
} while (FindNextFile(hfind, &find));
FindClose(hfind);
}
int wmain()
{
vector<wstring> sa;
files_and_folders(sa, L"c:\program files (x86)\Mozilla Firefox");
for (int i = 0; i < (int)sa.size(); i++)
wcout << sa[i] << endl;
system("pause");
return 0;
}

结果如下:

c:program files (x86)Mozilla FirefoxAccessibleMarshal.dll
c:program files (x86)Mozilla Firefoxapplication.ini
c:program files (x86)Mozilla Firefoxbreakpadinjector.dll
c:program files (x86)Mozilla Firefoxbrowser
c:program files (x86)Mozilla Firefoxbrowserblocklist.xml
c:program files (x86)Mozilla Firefoxbrowserchrome.manifest
...

您可能希望对结果进行排序。我也有一些排序函数,我必须从MFC转换它们。