Копирование строки из указателя на строку - PullRequest
2 голосов
/ 23 августа 2011

Я разрабатываю некоторый код, который читает имена файлов с SD-карты (используя FatFs) и отображает их на экране.Вот фрагмент того, что у меня работает, это распечатывает файлы на карте, как и ожидалось -

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, и я потерян!

Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

1 голос
/ 23 августа 2011

Первая проблема: в настоящее время ваш список файлов представляет собой массив символов, в то время как он должен быть массивом строк .Поэтому объявите его как

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 голосов
/ 23 августа 2011

Вы должны использовать следующее определение массива

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:

...