2011-08-23 164 views
2

我正在開發一些從sd卡中讀取文件名的代碼(使用FatFs)並將它們顯示在屏幕上。下面是我的工作有什麼,這種打印出預期的卡上的文件snipet -將指針中的字符串複製到字符串

FRESULT result; 
     char *path = '/'; //look in root of sd card 
     result = f_opendir(&directory, path); //open directory 
     if(result==FR_OK){ 
      for(;;){ 
       result = f_readdir(&directory, &fileInfo); //read directory 
       if(result==FR_OK){ 
        if(fileInfo.fname[0]==0){ //end of dir reached 
         //LCD_UsrLog("End of directory.\n"); 
         break; 
        } 
        if(fileInfo.fname[0]=='.')continue; //ignore '.' files 

        TCHAR *fn_ptr; //file name, why a pointer? 
        fn_ptr=&fileInfo.fname; //get file name    
        LCD_UsrLog("%s\n",fn_ptr); 
        for(delay=0;delay<0x0FFFFF;delay++){ShortDelay();} //delay to display 

       }//end result==fr_ok 
      }//end for 
     }//end result==fr_ok 

typedef char TCHAR 

typedef struct { 
DWORD fsize;   /* File size */ 
WORD fdate;   /* Last modified date */ 
WORD ftime;   /* Last modified time */ 
BYTE fattrib;  /* Attribute */ 
TCHAR fname[13];  /* Short file name (8.3 format) */ 

} FILINFO;

我需要將文件的名稱複製到一個數組進行處理但是我已經嘗試了幾種方法,但似乎無法使數組工作。我試圖創建一個任意大的TCHAR數組並取消引用文件名指針,但這會打印垃圾。

FRESULT result; 
     char *path = '/'; //look in root of sd card 
     TCHAR fileList[50]; 
     u32 index=0; 
     result = f_opendir(&directory, path); //open directory 
     if(result==FR_OK){ 
      for(;;){ 
       result = f_readdir(&directory, &fileInfo); //read directory 
       if(result==FR_OK){ 
        if(fileInfo.fname[0]==0){ //end of dir reached 
         //LCD_UsrLog("End of directory.\n"); 
         break; 
        } 
        if(fileInfo.fname[0]=='.')continue; //ignore '.' files 

        TCHAR *fn_ptr; //file name, why a pointer? 
        fn_ptr=&fileInfo.fname; //get file name    

        fileList[index]=*fn_ptr; 
        LCD_UsrLog("%s\n",fileList[index]); 
        for(delay=0;delay<0x0FFFFF;delay++){ShortDelay();} //delay to display 
        index++; 
       }//end result==fr_ok 
      }//end for 
     }//end result==fr_ok 

我懷疑這是關於指針或字符數組的正確使用一個簡單的錯誤,但它已經4年以上,因爲我已經最後一個接觸C和我迷路了!

任何幫助將不勝感激。

回答

1

第一個問題:目前你的文件列表是一個字符數組,而它應該是一個字符串數組。所以它聲明爲

TCHAR* fileList[50]; 

然後分配適當長度的字符串每個文件名(不要忘記的終止0炭額外的空間)。您還需要明確地將文件名複製到名稱列表中,因爲fileInfo的內容會在每個循環中被覆蓋,所以只需存儲指針就會導致列表中包含最後一個文件的名稱50次。

所有的一切,你需要的東西是這樣的:

   if(fileInfo.fname[0]=='.')continue; //ignore '.' files 

       fileList[index] = malloc(strlen(fileInfo.fname) + 1); 
       strcpy(fileList[index], fileInfo.fname); 

       LCD_UsrLog("%s\n",fileList[index]); 

(聲明:任何保證這個工程,因爲它是,我沒有機會來測試它,但我希望這給你的想法)。

或者,如果您知道文件名長度的上限,則可以聲明具有固定長度的文件名數組,並擺脫動態分配。但是,您應該使用strncpy而不是strcpy來保證安全,以防止緩衝區溢出。而這也需要終止0字符被追加,又是在安全方面:

TCHAR fileList[50][MAX_FILENAME_LENGTH + 1]; 

... 
strncpy(fileList[index], fileInfo.fname, strlen(fileInfo.fname)); 
fileList[index][MAX_FILENAME_LENGTH] = '\0'; 
+0

這是完美的。非常感謝您的快速響應。現在我必須弄清楚如何改變fileList數組來動態改變它的大小(這意味着我很快可能會回到另一個問題!) – David

+0

Peter,使用第二種方法 - 多維數組有什麼優勢?這使得打印文件名更加複雜,我看不到任何好處(至今)。 – David

+0

@David,好處是內存分配在堆棧上,因此一旦超出範圍就會自動釋放內存。使用動態分配,您還需要手動釋放內存,否則會導致內存泄漏。 –

0

您必須使用下一個數組定義

TCHAR fileList[50][13]; 

...

   if(fileInfo.fname[0]=='.')continue; //ignore '.' files 

       strncpy(fileList[index], sizeof(fileList[index]), fileInfo.fname); 
       LCD_UsrLog("%s\n",fileList[index]); 

或用於動態記憶。不要忘記釋放記憶!

TCHAR* fileList[50]; 

...

   if(fileInfo.fname[0]=='.')continue; //ignore '.' files 

       fileList[index]=strdup(fileInfo.fname); 
       LCD_UsrLog("%s\n",fileList[index]); 

PS: