我正在开发一些代码,它从SD卡中读取文件名(使用FatF)并将它们显示在屏幕上。这是我工作的内容,它按预期打印出卡片上的文件 -
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年多了!
非常感谢任何帮助。
答案 0 :(得分: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';
答案 1 :(得分: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: