-3

現在のディレクトリとそのサブディレクトリにあるすべてのファイルを検索するアプリケーションを作成しようとしています。完全には理解できない次の問題があります

  1. 私の場合、どのように再帰GetFiles()関数を使用する必要がありますか、そして
  2. 関数内で動的に割り当てられた空きメモリが必要な場合PathCreator()。このプログラムを一部のディレクトリ(サブディレクトリなし)でのみテストすると、機能します(コメント付きのコードを参照してください_tmain())。しかし、すべてのファイルを取得しようとすると、クラッシュが発生します。

これが私のコードです:

// ConsoleApplication1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <iostream>
#define SIZE 300

int is_directory(wchar_t *p)
{
    wchar_t temp[300];
    int i;
    i = 0;
    while(*p != '\0')
    {
        temp[i] = *p;
        p++;
        i++;
    }
    temp[i] = '\\';
    i++;
    temp[i] = '\0';
    WIN32_FIND_DATA file;
    HANDLE search_hendle = FindFirstFile(temp, &file);
    long error = GetLastError();
    if(error == 267)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}


wchar_t *PathCreator(wchar_t *dir, wchar_t *fileName)
{
    wchar_t* path = new wchar_t[SIZE];
    int j = 0;
    while(j < SIZE)
    {
        path[j] = '\0';
        j++;
    }
    int i;
    i = 0;
    while(*dir != '*' && *dir != '\0')
    {
        path[i] = *dir;
        i++;
        dir++;
    }
    wchar_t *t = fileName;  
    while(*t != '\0')
    {
        path[i] = *t;
        i++;
        t++;
    }
    path[i] = '\0';
    return path;
} 

wchar_t* allFlsArr[SIZE];
int i = 0;
wchar_t **GetAllFiles(wchar_t* dir)
{
    WIN32_FIND_DATA file;
    HANDLE search_hendle = FindFirstFile(dir, &file);
    if(search_hendle)
    {
        do
        {
            wchar_t *p = PathCreator(dir,file.cFileName);
            allFlsArr[i++] = p;
        }
        while(FindNextFile(search_hendle, &file));
        allFlsArr[i] = '\0';
    }
    CloseHandle(search_hendle);
    return allFlsArr;
}

void GetFiles(wchar_t *dir)
{
    wchar_t **filePaths = 0;
    filePaths = GetAllFiles(dir);
    int  i = 0;
    while(filePaths[i] != '\0'){
        if(!is_directory(filePaths[i]))
        {
            std::wcout << filePaths[i] << std::endl;
        }
        else
        {
            GetAllFiles(filePaths[i]);
        }
    }
    delete [] filePaths;
}
int _tmain(int argc, _TCHAR* argv[])
{
    /*wchar_t **wch = GetAllFiles(L"C:\\*");
    int i = 0;
    while( *wch != '\0')
    {
        std::wcout << *wch << std::endl;
        wch++;
    }*/
    GetFiles(L"C:\\*");
}
4

1 に答える 1

3

まず、なぜ、、または...のような関数を使用wcscpywcscatず、常にすべての文字列とバッファの操作を手動で行うのか疑問に思います!?ただし、コードにいくつかの問題があることに加えて、次のようになります。

  • ワイド文字列pointers()の単一配列を使用して、のallFlsArr結果を呼び出し元に返します。GetAllFilesその結果を反復処理するときにGetAllFiles、を上書きするために再度呼び出しますallFlsArr

  • GetAllFilesあなたは使用の結果を解放していますdelete[] filePathsが、それは実際allFlsArrにはグローバル変数であり、削除することはできません。std::vector<std::wstring>必要ないことを試してくださいdelete/new

  • ファイル名の配列が非常に小さいため、300を超えるファイルまたはフォルダーがあるフォルダー内のファイルを受け入れることができませんstd::vector<std::wstring>。サイズが大きくなり、任意の数のアイテムを受け入れることができるので、もう一度試してください。

  • を使用してフォルダを検索する*と、Windowsはそれらを検索してはならない余分なディレクトリに戻ります(...)。それらをスキップする必要があります(if(!wcscmp(file.cFileName, L".") || !wcscmp(file.cFileName, L"..")) continue

  • を使用する必要があるときCloseHandleに、から戻ってきたハンドルを閉じるために使用しFindFirstFileますFindClose

だからあなたはこのようなものを持っているかもしれません:

std::vector<std::wstring> list_files( wchar_t const* folder )
{
    std::wstring root = folder;
    if( folder.back() == '*' ) folder.erase( folder.end() - 1 );
    if( folder.back() != '\\' ) folder.push_back( '\\' );

    std::vector<std::wstring> res;
    WIN32_FIND_DATA file;
    HANDLE hSearch = FindFirstFileW( folder, &file );
    if( hSearch != INVALID_HANDLE_VALUE ) {
        do {
            if( !wcscmp(file.cFileName, L".") ||
                !wcscmp(file.cFileName, L"..") )
                continue;
            res.push_back( root + file.cFileName );
            if( file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
                // search for sub folders of this folder
                std::vector<std::wstring> tmp =
                    list_files( (root + file.cFileName) + L"\\*" );
                // all all items to end of our result!
                res.insert( res.end(), tmp.begin(), tmp.end() );
            }
        } while( FindNextFileW(hSearch, &file) );
        FindClose( hSearch );
    }
    return res;
}
于 2012-10-15T16:53:49.207 に答える