Получение списка каталогов - PullRequest
0 голосов
/ 05 января 2012

У меня проблема с векторами, которые я пытался решить уже довольно давно.Я просто опубликую код сразу и объясню его.

#include "filesystem.h"
#include <vector>
using namespace Filesystem;

wchar_t** Path::ListDir()
{
    /*struct dirEntry
    {
        wchar_t entry[MAX_PATH];
    };*/
    vector<wchar_t*> pathList = vector<wchar_t*>();
    WIN32_FIND_DATA findData;
    HANDLE dirHandle = new HANDLE;
    wchar_t* path = L"C:\\*";

    dirHandle = FindFirstFile(path, &findData);
    if (dirHandle == INVALID_HANDLE_VALUE)
        return NULL;

    while (FindNextFile(dirHandle, &findData) != 0)
    {
        pathList.push_back(findData.cFileName);
    }

    FindClose(dirHandle);

    return NULL;
}

Это часть класса файловой системы, который я сейчас кодирую.Предполагается перечислить все файлы в каталоге и вернуть их в виде двумерного массива строк.Если я делаю это так, он заполняет список последним файлом, умноженным на количество файлов в папке.Что не то, что я хочу это сделать.Я думал, что это может быть, так как я доставляю указатель на push_back, но я не нашел способа это исправить.Я пишу на Windows, кстати.

Было бы неплохо, если бы кто-нибудь здесь имел представление о том, как это сделать.

Ответы [ 2 ]

1 голос
/ 05 января 2012

Вы сохраняете адрес findData.cFileName в vector N раз.

Вам нужно скопировать это. Возможно использование:

vector<std::wstring> pathList;

РЕДАКТИРОВАТЬ: Другие незначительные моменты:

vector<wchar_t*> pathList = vector<wchar_t*>();
HANDLE dirHandle = new HANDLE;

можно заменить на:

vector<wchar_t*> pathList;
HANDLE dirHandle;

Если вы должны вернуть wchar_t**, то (например):

// '+1' for NULL terminating string as the callers needs
// know where the array ends.
wchar_t** result = new wchar_t*[pathList.size() + 1];
*(result + pathList.size()) = 0;

for (size_t i = 0; i < pathList.size(); i++)
{
    wchar_t* name = new wchar_t[pathList[i].length() + 1];
    std::copy(pathList[i].begin(), pathList[i].end(), name);
    *(name + pathList[i].length()) = L'\0';
    *(result + i) = name;
}

return result;

Вызывающий должен запомнить delete[] возвращенный массив:

Path p;
wchar_t** list = p.ListDir();
...
for (size_t i = 0; 0 != *(list + i); i++)
{
    delete[] *(list + i);
}
delete[] list;

Хотя, поскольку это C ++, вы должны использовать std::vector<std::wstring>.

1 голос
/ 05 января 2012

В вашем решении все указатели в вашем векторе одинаковы и указывают на последнюю строку cString (она примерно указывает на экземпляр findData в стеке).После вызова FindNextFile () вы должны скопировать его результат .Попробуйте что-то подобное:

std::vector<std::wstring> pathList;
//...
{
  pathList.push_back(std::wstring(findData.cFileName));
}

Сам не скомпилировал.Но у вас есть грубая идея здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...