Вопрос по языку СИ и библиотеке Petit FatFS

Обсуждаем контроллеры компании Atmel.
Ответить
Открыл глаза
Аватара пользователя
Сообщения: 56
Зарегистрирован: Чт сен 04, 2014 18:21:01

Сообщение KaiTheKat »

Здравствуйте. В библиотеке Petit FatFS (http://microsin.net/programming/file-sy ... ystem.html) есть функция pf_readdir(), которая получает имя файла в указанной директории. Имя файла хранится в fno.fname . Как открыть этот файл с помощью функции pf_open() ?
В чем проблема: В pf_open() нужно указать путь к файлу целиком (путь/имя.формат), а в fno.fname хранится только (имя.формат).
Тот же вопрос по другому: Как в языке СИ добавить значение одной (переменной, массива и т. д.) к другой?
К примеру есть char a[] = "pyt/" и char b[] = "ima.format", как к новому (массиву или переменному, указателю и т. п.) добавить a и b, чтобы в итоге там хранился значение c[] = "pyt/ima.format" .
Как я пробовал и это не работала (все if while и нужные переменные будем считать объявленными):

Привожу только то, что не работает, а не работает тут pf_open(path); Т. е если указать pf_open("pyt/ima.format") все работает, файл открывается.

char *path = "dir";
int i = strlen(path);

disk_initialize();
pf_mount(&fs);
pf_opendir(&dir, path);
pf_readdir(&dir, &fno);
sprintf(&path, "/%s", fno.fname);
pf_open(path);
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4752
Зарегистрирован: Вс янв 24, 2010 13:14:02
Откуда: Омск

Сообщение vem566 »

Не пишу на С для АВР, но в классическом С есть функция StrCat(str1,str2...).
Попробовал АВР Студию, вроде не ругается. Похоже есть она.
Реклама
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница

Сообщение urry »

ну с чего оно должно работать...
размер массива path, созданного через указатель, всего 4 байта - 3 байта + завершающий 0
char *path = "dir";
А затем вы в этот массив пытаетесь запихнуть еще что-то.
"Нельзя впихнуть невпихуемое" (с) Плющ.
Контактная информация:
Открыл глаза
Аватара пользователя
Сообщения: 56
Зарегистрирован: Чт сен 04, 2014 18:21:01

Сообщение KaiTheKat »

urry писал(а):ну с чего оно должно работать...
размер массива path, созданного через указатель, всего 4 байта - 3 байта + завершающий 0
char *path = "dir";
А затем вы в этот массив пытаетесь запихнуть еще что-то.
"Нельзя впихнуть невпихуемое" (с) Плющ.
Не соглашусь:
char *path = "dir";
path = "123hsdak343";
Так можно делать, компилятор не ругается и в командной строке все прекрасно работает (просто значение path изменился). Но суть не в этом.
Пример взят из документации http://microsin.net/programming/file-sy ... d-dir.html:
char *path = "dir";
int i = strlen(path);

disk_initialize();
pf_mount(&fs);
pf_opendir(&dir, path);
pf_readdir(&dir, &fno);
sprintf(&path, "/%s", fno.fname);
pf_open(path);

Так что, тут никаких ошибок нет, да и компилятор их не выдает. Просто pf_open возвращает ошибку FR_NO_FILE . В path записался что-то другое, а не путь до файла.

Файлы в корневом каталоге открываются, когда вот так (все работает, воспроизводит):
pf_opendir(&dir, "/");
pf_readdir(&dir, &fno);
pf_open(fno.fname);

Но, если нужно открыть какую то папку, не получается. Не знаю, как вставить имя папки в pf_open()
pf_opendir(&dir, "/papka");
pf_readdir(&dir, &fno);
??? pf_open(fno.fname); ??? Перед fno.fname нужно еще добавить "/papka", но как это сделать?
sprintf(&path, "/%s", fno.fname); не помогает ( в path записался не то, что нам нужно)
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 4752
Зарегистрирован: Вс янв 24, 2010 13:14:02
Откуда: Омск

Сообщение vem566 »

Может и глюк компилятора.
А почему не попробовать функцию StrCat, о которой писал раньше?
Реклама
pcb
Опытный кот
Сообщения: 833
Зарегистрирован: Пт авг 12, 2011 09:14:27
Откуда: Млечный путь/Земля/РФ/Екатеринбург

Сообщение pcb »

KaiTheKat писал(а):Не соглашусь:
char *path = "dir";
path = "123hsdak343";
Давай разберём этот пример.

Создается массив с "dir"
Потом создается переменная указатель *path и ему присваивается адрес "dir"
Далее создаётся новый массив и переменной присваивается адрес нового массива

Сама же переменная *path, имеет тип инт, short int или всё в этом духе, в ней массив непосредственно не хранится.
KaiTheKat писал(а):sprintf(&path, "/%s", fno.fname);
pf_open(path);

Вы когда нибудь слышали об экранировании спец символов? =)
рекомендую почитать
Разработал:
-BLDC
-ФУОЗ/МПСЗ
-SMART BMS
-ECU/EDC на STM32F4(43%)+CPLD(57%)
-Моноинжектор на ATSAMD20G16
-контроллер эффектов для RGB LED ленты
-умные часы/обратный счет/секундомер
-устройство измерения емкости АКБ
Реклама
Открыл глаза
Аватара пользователя
Сообщения: 56
Зарегистрирован: Чт сен 04, 2014 18:21:01

Сообщение KaiTheKat »

vem566 писал(а):А почему не попробовать функцию StrCat, о которой писал раньше?
Пробовал, так:?
char str[100];
strcpy( str, "/papka1/" );
strcpy( str, fno.fname );

Все равно возвращает FR_NO_FILE
Открыл глаза
Аватара пользователя
Сообщения: 44
Зарегистрирован: Пт фев 14, 2014 21:22:19
Откуда: Енотоград

Сообщение main_enot »

strcpy копирует из одного массива в другой
strcat добавляет к массиву.
надо так:
char str[100];
strcpy( str, "/papka1/" );
strcat( str, fno.fname );
Контактная информация:
Открыл глаза
Аватара пользователя
Сообщения: 56
Зарегистрирован: Чт сен 04, 2014 18:21:01

Сообщение KaiTheKat »

vem566 писал(а):Вы когда нибудь слышали об экранировании спец символов? =)
ДА, но как это поможет здесь, можете привести пример с моим кодом, если не сложно?
pcb писал(а):Создается массив с "dir"
Потом создается переменная указатель *path и ему присваивается адрес "dir"
Далее создаётся новый массив и переменной присваивается адрес нового массива

Сама же переменная *path, имеет тип инт, short int или всё в этом духе, в ней массив непосредственно не хранится.
Все верно, в старый массив ничего не впихивается, а создается новый.
urry писал(а):А затем вы в этот массив пытаетесь запихнуть еще что-то.
вот с этим я и не был согласен. То, что указатель хранить адрес ячейки памяти я знаю, но в функцию pf_open(const char* FileName), как раз и нужно передать такой тип указателя на переменной. Что именно не правильно в моем примере или в примере документации на библиотеку (http://microsin.net/programming/file-sy ... d-dir.html) ? Так как я пример взял оттуда, там то же самое.
Открыл глаза
Аватара пользователя
Сообщения: 56
Зарегистрирован: Чт сен 04, 2014 18:21:01

Сообщение KaiTheKat »

KaiTheKat писал(а):надо так:
char str[100];
strcpy( str, "/papka1/" );
strcat( str, fno.fname );
Спасибо, подсказали по существу. Теперь все работает как надо FR_OK . Был не внимателен, как я мог strcpy написать два раза и не заметить.

Не могли бы еще вот с этим помощь (вопрос тоже по библиотеке Petit FatFS):

FILINFO fno;
DIR dir;

pf_readdir(&dir, &fno);

В документации написано: "Когда в параметре FileInfo передан нулевой указатель (null pointer), индекс чтения директории будет сброшен в начало (т. е. вызовы pf_readdir будут заново читать элементы директории)." Что это значит? Когда прочитаны все файлы, как сделать чтобы они по новой начали читаться?
Открыл глаза
Аватара пользователя
Сообщения: 56
Зарегистрирован: Чт сен 04, 2014 18:21:01

Сообщение KaiTheKat »

Все сам разобрался pf_readdir(&dir, NULL); Спс всем за советы, подсказки, обсуждения.
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница

Сообщение urry »

Не соглашусь:
char *path = "dir";
path = "123hsdak343";
Так можно делать, компилятор не ругается и в командной строке все прекрасно работает (просто значение path изменился). Но суть не в этом.
?
С чем вы не согласны ?
Хочу деталей.
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

KaiTheKat писал(а): Не соглашусь:

Код: Выделить всё

char *path = "dir";
path = "123hsdak343";
Так можно делать
Сравните с изначальным вариантом :

Код: Выделить всё

char *path = "dir";
sprintf(&path[i], "/%s", fno.fname);
Разницу замечаете ? :facepalm:
Или разжевать ?
Ответить

Вернуться в «AVR»