2011-08-23 31 views
2

私は、(FatFsを使用して)SDカードからファイル名を読み取り、それらを画面に表示するコードを開発しています。ここに私が働いているものの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 

私は、これは、ポインタや文字の配列の適切な使用に関する単純なミスである疑いがあるが、私は最後のCに触れてきたので、それが4年以上されていると私は迷ってしまいました!

ご協力いただければ幸いです。

答えて

1

最初の問題:現在、ファイルリストは文字の配列ですが、の文字列の配列にする必要があります。

TCHAR* fileList[50]; 

として宣言し、各ファイル名に適切な長さの文字列を割り当てます(終端0文字の余分なスペースを忘れないでください)。 の内容が各ループサイクルで上書きされるため、ファイル名を明示的に名前リストにコピーする必要があります。ポインタを保存するだけで、最後のファイルの名前が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]); 

(免責事項:それは、これが動作することを保証無し、私はそれをテストする機会を持っていませんが、うまくいけば、これはあなたのアイデアを与える)を。

また、ファイル名の長さの上限を知っていれば、固定長のファイル名の配列を宣言し、動的割り当てを取り除くことができます。しかし、バッファオーバーフローを防ぐためには、strcpyの代わりにstrncpyを安全な側にする必要があります。そして、これはまた、終端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、2番目のアプローチ、つまり多次元配列?これは、ファイル名の印刷をはるかに複雑にしているので、私は(まだ)どんな利益も見られません。 – 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: