Copying a string from a pointer to a string
I'm developing some code which reads file names from an sd-card (using FatFs) and displays them to the screen. Here's a snipet of what I have working, this prints out the files on the card as expected -
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
Where
typedef char TCHAR
and
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;
I need to copy the names of the files into an array for processing however I've tr开发者_运维问答ied a few ways but can't seem to get the array working. I have tried creating an arbitrarily large array of TCHARs and dereferencing the file name pointer but this prints garbage.
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
I suspect this is a simple mistake regarding pointers or the proper usage of an array of chars but it has been 4+ years since I've last touched C and I'm lost!
Any help would be greatly appreciated.
First problem: currently your file list is an array of chars, while it should be an array of strings. So declare it as
TCHAR* fileList[50];
then allocate the strings of proper length for each filename (not forgetting the extra space for the terminating 0 char). You also need to explicitly copy the filenames into your name list, because the contents of fileInfo
get overwritten in each loop cycle, so simply storing the pointers would result in your list containing the name of the last file 50 times.
All in all, you need something like this:
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]);
(Disclaimer: No guarantee that this works as it is, I have no chance to test it, but hopefully this gives you the idea).
Alternatively, if you know the upper limit of the filename length, you can declare an array of filenames with fixed length, and get rid of dynamic allocation. But then you should use strncpy
instead of strcpy
to be on the safe side, to prevent buffer overflows. And this also requires the terminating 0 character to be appended, again to be on the safe side:
TCHAR fileList[50][MAX_FILENAME_LENGTH + 1];
...
strncpy(fileList[index], fileInfo.fname, strlen(fileInfo.fname));
fileList[index][MAX_FILENAME_LENGTH] = '\0';
You must use next array definition
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]);
or for dynamic memory. Don't forget to free memory!
TCHAR* fileList[50];
...
if(fileInfo.fname[0]=='.')continue; //ignore '.' files
fileList[index]=strdup(fileInfo.fname);
LCD_UsrLog("%s\n",fileList[index]);
PS:
精彩评论