简体   繁体   中英

Extracting a file name from the path

Alright, I have the following:

wchar_t **filePathList;

This holds a list of files that are being added to a listbox. Problem is that they show the whole file path, and I want to get just the name. I thought about using:

wchar_t *tempChar;

to start at the end of the filePathList, and work the way back until I get to a \\ . The problem is I'm not absolutely sure how to manage this. This is the code I've got so far:

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();
}

Problem is that Visual Studio is reporting tempChar as a "bad ptr". I admit that I'm still really green when it comes to programming, and know very little about pointers, much less double pointers. But any help would be very much appreciated. Thank you.

The function you're working with is 76 lines long as written. That's not catastrophically long, but it's getting to the point where it'll be hard to reason about. It would probably be worthwhile to separate this function into a couple of smaller functions. One problem you're working on is how to extract a filename from a full path. You could write a function with a signature like:

char *filename_from_path(const char *fullpath);

that takes in a full path and returns a new string with just the filename. (NB: you'll have to be careful about who allocates and frees the filename string). The neat thing about breaking down a function like that is that there's often good advice on how to do the little sub-pieces:

Extract file name from full path in C using MSVS2005 , for example.

Separating out that logic will make it easier to reason about the larger loop you're working on.

The error is in this bit of code:

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

A few problems here:

  1. len does not include the null-terminator so you are not allocating enough memory. You need one more character.
  2. You have failed to call DragQueryFile a second time to fill out the buffer.
  3. Your first access of filePathList[i][index] is out of bounds because index is beyond the end of the array.
  4. Since filePathList[i] is not initialized the loop probably counts down to index of 0 and then produces an access violation.
  5. Even when you fix all these errors you need to test for index>=0 in your loop in case the string contains no path separators.

I've not looked at any other code in your question but I'm willing to bet that I've not found all the errors. This should be enough for now.

Joachim's advice to use _splitpath is very sound but on the flip side, you really need to master this type of coding.

It is also possible you could open the file to find it's name. Although that's probably just as slow as going through the path.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM