2011-12-20 8 views
0

Хорошо, у меня есть следующие:Извлечение имени файла из пути

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». Я признаю, что я все еще очень зеленый, когда дело доходит до программирования, и мало знаю о указателях, а тем более о двойных указателях. Но любая помощь была бы очень оценена. Спасибо.

+0

Можете ли вы использовать ['_splitpath'] (http://msdn.microsoft.com/en-us/library/e737s6tf.aspx)? –

+0

Почему люди этого не делают? –

+0

Возможно, потому что человек, задающий вопрос, попытался (и, по-видимому, не смог) сделать что-то, для чего существует стандартная функция? –

ответ

3

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

char *filename_from_path(const char *fullpath); 

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

Extract file name from full path in C using MSVS2005, например.

Разделение этой логики упростит рассуждение о более крупном цикле, над которым вы работаете.

+0

+1 что это хороший совет –

+0

Хорошо, поэтому я взял пример по ссылке и изменил его. Он работал так полностью. Большое спасибо. – MyCodeSucks

1

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

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 в вашем цикле, если строка не содержит разделителей путей.

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

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

+0

Все это ранее работало до моей попытки чтобы получить только имя файла. Раньше никогда не было проблемы с 'len'. И я на самом деле не получаю ошибку. Я просто вижу талисман в моем списке. – MyCodeSucks

+0

ну, я нашел много ошибок в вашем коде. Вам решать, что есть ошибки. Их гораздо больше. –

+0

О, вы не получите от меня никаких аргументов. Грустная часть - это единственная часть, которую я написал, это цикл, который вы указали. Я сейчас смотрю на '_splitpath'. Видя, что это будет то, что я использую. Спасибо за вашу помощь. Я ценю это. – MyCodeSucks

0

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

+0

Это действительно не способ сделать это. Сожалею. –

Смежные вопросы