Я пытаюсь разработать устройство для копирования файлов с одного USB-накопителя на другой, используя оба FAT-Filesystem. Поэтому я использую микроконтроллер Vinculum II FTDI. Код написан на C.Добавление одного элемента в связанный список создает два элемента?
Чтобы иметь возможность копировать все файлы, мне нужно знать имена (под) каталогов на диске, потому что каждый из них должен обрабатываться отдельно. Существует функция on-chip для сканирования текущего каталога для файлов и подкаталогов («fat_dirTableFindFirst()» и «fat_dirTableFindNext()»).
Мне нужно сохранить имена всех каталогов (тип данных char *), которые я получил от сканирования динамически. Я решил использовать связанный список. Я использую его как стек (LIFO).
Это важно для понимания кода, поэтому я еще раз подчеркну, что мне приходится сканировать каждый каталог отдельно. Поэтому сначала я просматриваю корневой каталог для его записей. Те, которые являются дополнительными подкаталогами, попадают в стек.
После завершения сканирования в первом каталоге я захватываю верхний подкаталог со стека (pop()). Затем я нажимаю маркер места «пробел» в стек, чтобы позже узнать, что я входил в более глубокий уровень/слой этого «дерева каталогов». Если во время сканирования я не найду дальнейшие каталоги, я вернусь на последний уровень и так далее. Следовательно, процедура сканирования должна быть похожа на предпросмотр дерева.
Он отлично работает, если есть макс. один подкаталог в каждом каталоге. Но если их несколько, я получаю запутанную ошибку: первый каталог задан правильно, но все следующие записи отображаются дважды в стеке! Из-за этого контроллер копирует те же файлы снова и снова.
Одиночный переход по программе не позволяет понять, почему это происходит. Код также записывает содержимое стека до и после каждого нажатия или pop в файл .txt с теми же запутанными результатами. Он немного похож на операцию push() - создает два элемента, но только если он вызывается во время этого цикла ... while.
Вот интересная часть кода. vos_free() унд vos_malloc() эквивалентна обычной свободной() таНос() вызовы (Ordner это немецкое слово для каталога или папки):
struct ordner {
char* data;
struct ordner* next;
};
void push(struct ordner** headRef, char* dirName)
{
struct ordner* newOrdner;
if (newOrdner = vos_malloc(sizeof(struct ordner)) != NULL)
{
newOrdner->data = dirName;
newOrdner->next = *headRef;
*headRef = newOrdner;
}
}
char* pop(struct ordner** headRef)
{
struct ordner* temp;
char* value = " ";
temp = *headRef;
value = *headRef->data; // "save" last element to return it
*headRef = temp->next;
vos_free(temp);
return (value);
}
while(1)
{
file_context_t fileToCopy; // File-Handle
struct ordner dummy;
struct ordner* head = &dummy;
dummy.next = NULL;
dummy.data = begin;
newScan: fat_dirTableFindFirst(fatContext1, &fileToCopy); if(firstRun == 0) // First filename in first scan is the name of the disk, and has to be ignored
{
fat_dirTableFindNext(fatContext1, &fileToCopy);
firstRun = 1;
}
do
{
// if the entry is a Directory, add it to the stack
if (fat_dirEntryIsDirectory(&fileToCopy) == 1)
{
strncpy(nextDir, (char*) &fileToCopy, 11);
push(&head, nextDir);
// The next if-statement usually cannot be true, because there can't be
// two files with the same name in one directory and the different levels/layers
// of sub-directories are separated by a place marker, but actually it becomes
// true (LEDs are flashing because of blink(3))
if (head->data == head->next->data) blink(3);
}
else
{
strncpy(nextFile, (char*) &fileToCopy, 11);
copyFile(fatContext1,fatContext2, nextFile); }
} while (fat_dirTableFindNext(fatContext1, &fileToCopy) == FAT_OK); // perform scan, until all items of the directory were scanned
// then the next (sub-)directory has to be opened to scan it
// there are two possibilities to proceed:
// (1) no directory found ("space" on stack) --> go back to last layer and open & scan the next directory there (if there is another one)
// (2) a new sub-directory was found --> open & scan it
change_layer: if (head != NULL)
{
nextDir = pop(&head); // get next Directory from stack
// Possibility (1)
if (nextDir == space)
{
// move back to last Directory
goto change_layer;
}
// Possibility (2): neue Unterordner gefunden
else
{
push(&head, space); // sign for entering next layer
//...
// open next directory
//...
goto newScan;
}
}
}
} // End while(1)
Можете ли вы сказать мне, почему это происходит, что появляется один пункт дважды в стеке? Является ли мой алгоритм неправильным?
После нескольких часов и часов повторного поиска и кодирования я не мог решить эту проблему.
Пожалуйста, простите мне мой плохой стиль программирования с теми ассемблере петель, и мой плохой английский (я из Германии :))
Заранее спасибо
Chris
Спасибо за этот ответ. Я сразу понял, что я сделал не так. Теперь стек работает отлично :) Система не знает strdup(), но я только вручную выделил память и скопировал строку. –
Я рад, что смог помочь. <^_^> – steveha