将C ++目录树数据转换为向量

时间:2015-04-14 08:35:45

标签: c++ winapi tree filesystems tree-traversal

我可以使用Windows API FindFirstFile + FindNextFile遍历指定目录及其所有子目录,并将所有目录名和文件名存储在struct

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

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

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

修改

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

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

}

1 个答案:

答案 0 :(得分:1)

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

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 Firefox\AccessibleMarshal.dll
c:\program files (x86)\Mozilla Firefox\application.ini
c:\program files (x86)\Mozilla Firefox\breakpadinjector.dll
c:\program files (x86)\Mozilla Firefox\browser
c:\program files (x86)\Mozilla Firefox\browser\blocklist.xml
c:\program files (x86)\Mozilla Firefox\browser\chrome.manifest
...

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