Извлечение имени файла из пути - PullRequest
0 голосов
/ 21 декабря 2011

Хорошо, у меня есть следующее:

wchar_t **filePathList;

Содержит список файлов, которые добавляются в список.Проблема в том, что они показывают полный путь к файлу, и я хочу получить только имя.Я думал об использовании:

wchar_t *tempChar;

, чтобы начать в конце filePathList и работать до тех пор, пока не доберусь до \.Проблема в том, что я не совсем уверен, как справиться с этим.Вот код, который я получил до сих пор:

afx_msg void Send::OnDropFiles(HDROP hDropInfo)
{
    if(uploadInProgress)
    {
        MessageBox(L"Please wait for current upload to finish before adding files", L"Upload in progress", MB_OK);
        return;
    }

    int len;
    int prevNFiles = nFiles;
    wchar_t **buffer = filePathList;
    wchar_t *tempChar = NULL;

    // get number of files dropped into window
    nFiles += DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);

    filePathList = (wchar_t**)malloc(nFiles*sizeof(wchar_t*));
    if(!filePathList)
    {
        MessageBox(L"FilePath list memory allocation failed", L"Error");
        nFiles = 0;
        if(buffer)
        {
            for(int i=0; i<prevNFiles; i++)
            {
                if(buffer[i]) free(buffer[i]);
            }
            free(buffer);
        }
        return;
    }
    memset(filePathList, 0, nFiles*sizeof(wchar_t*));

    // get file names
    for(int i=0; i<nFiles; i++)
    {
        if(i < prevNFiles)
        {   // previously entered files
            filePathList[i] = buffer[i];
            continue;
        }
        // newly dropped files
        len = DragQueryFile(hDropInfo, i-prevNFiles, NULL, 0)+1;    // 1 for \0
        tempChar = (wchar_t*)malloc(len*sizeof(wchar_t));
        filePathList[i] = (wchar_t*)malloc(len*sizeof(wchar_t));

        int index = len;

            // Attempting to iterate through the path to get the file name
        while(filePathList[i][index] != '\\')
        {
            tempChar = filePathList[index];
            index--;
        }

        filePathList[i] = tempChar;
        if(!filePathList[i])
        {
            MessageBox(L"FilePath memory allocation failed", L"Error");
            for(int j=0; j<i; j++)
            {
                if(filePathList[j]) free(filePathList[j]);
            }
            free(filePathList); filePathList = NULL;
            nFiles = 0;
            break;
        }
        len = DragQueryFile(hDropInfo, i-prevNFiles, filePathList[i], len);

    }

    if(buffer) free(buffer);

    // display files
    UpdateFileListDisplay();
}

Проблема в том, что Visual Studio сообщает tempChar как «плохой ptr».Я признаю, что я все еще очень зеленый, когда дело доходит до программирования, и очень мало знаю об указателях, а тем более о двойных указателях.Но любая помощь будет очень цениться.Спасибо.

Ответы [ 3 ]

3 голосов
/ 21 декабря 2011

Функция, с которой вы работаете, имеет длину 76 строк. Это не катастрофически долго, но доходит до того, что об этом трудно будет рассуждать. Вероятно, стоило бы разделить эту функцию на пару более мелких функций. Одна из проблем, над которой вы работаете, заключается в том, как извлечь имя файла из полного пути. Вы можете написать функцию с подписью, например:

char *filename_from_path(const char *fullpath);

, который принимает полный путь и возвращает новую строку только с именем файла. (N.B .: Вы должны быть осторожны с тем, кто выделяет и освобождает строку имени файла). Отличная особенность разбивки подобной функции состоит в том, что часто есть хороший совет о том, как делать маленькие части:

Извлечение имени файла из полного пути в C, используя MSVS2005 , например.

Выделение этой логики облегчит рассуждение о большей петле, над которой вы работаете.

1 голос
/ 21 декабря 2011

Ошибка в этом бите кода:

tempChar = (wchar_t*)malloc(len*sizeof(wchar_t));
filePathList[i] = (wchar_t*)malloc(len*sizeof(wchar_t));

int index = len;

// Attempting to iterate through the path to get the file name
while(filePathList[i][index] != '\\')
{
    tempChar = filePathList[index];
    index--;
}

Несколько проблем здесь:

  1. len не включает нулевой терминатор, поэтому вы не выделяете достаточно памяти. Вам нужен еще один персонаж.
  2. Вы не смогли вызвать DragQueryFile во второй раз, чтобы заполнить буфер.
  3. Ваш первый доступ к filePathList[i][index] находится за пределами, поскольку index находится за концом массива.
  4. Поскольку filePathList[i] не инициализирован, цикл, вероятно, ведет обратный отсчет до index из 0 и затем выдает нарушение доступа.
  5. Даже когда вы исправляете все эти ошибки, вам нужно проверить на index>=0 в цикле, если строка не содержит разделителей пути.

Я не видел ни одного другого кода в вашем вопросе, но готов поспорить, что я не нашел все ошибки. Этого должно быть достаточно на данный момент.

Совет Иоахима по использованию _splitpath очень здравый, но, с другой стороны, вам действительно нужно освоить этот тип кодирования.

0 голосов
/ 21 декабря 2011

Также возможно, что вы можете открыть файл, чтобы найти его имя. Хотя это, вероятно, так же медленно, как идти по пути.

...