Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Можно ли в typedef struct описать массив переменной длины
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Страницы: 1, 2
demiurg_spb
Цитата(west329_ @ Feb 24 2009, 15:05) *
Цель сделать поиск в буфере строки которая сидит во флеш памяти. Хочется использовать готовую процедуру.
тако реально сделать ? или надо свою процедуру писать
Для начала изучите библиотеку прежде чем сыпать вопросами, если не найдёте подходящей функции то тогда и поговорим.
zltigo
Цитата(demiurg_spb @ Feb 24 2009, 14:24) *
Так вроде как создаются ещё и лишние переменные типа указатель на строку, а в случае с [] нет.

Вроде! Вы просили создавать переменую с указателем? Нет? Так от какой сырости "создаются". Зачем фантазировать?
Сергей Борщ
Цитата(zltigo @ Feb 24 2009, 13:12) *
Ну и моему взгдляду приятнее
Код
char *test1 = "hello";
char *test2 = "test1 hello test2";

нежели []
Приятнее - возможно. Но есть маленькая разница: sizeof(test1) даст в случае [] размер памяти, выделенной под строку, а в случае * - размер указателя.
demiurg_spb
Цитата(zltigo @ Feb 24 2009, 15:08) *
Вроде! Вы просили создавать переменую с указателем? Нет? Так от какой сырости "создаются". Зачем фантазировать?

Конечно просил.
Ведь код
char* name = "Вася";
означает создать переменную типа char* с именем name и проинициализировать ее.
Где я ошибаюсь? Об этом я даже в мануале на avr-gcc читал.

Я не поленился и прогнал такой тест в gcc 4.3.2
и получил разницу в объёме использования ОЗУ на 2 байта в пользу [] естественно.
Зато флеши больше съело на 8 байт с какого-то перепугу - этого я не понялsad.gif
Код
char* name = "Вася";
//char name[] = "Вася";
volatile int i;

int main(void)
{
    i = strlen(name);
    return (0);
}
msalov
Цитата(demiurg_spb @ Feb 24 2009, 14:34) *
Я не поленился и прогнал такой тест в gcc 4.3.2
и получил разницу не в пользу char*.

Тут отличия гораздо глубже.
Код
char name[] = "Вася";
- создать массив длинны 5 байт и инициализировать его значением.
Код
char *name = "Вася";
- создать указатель на const char, то есть правильнее было бы
Код
const char *name = "Вася";
, причём при использовании не забываем что даже если объявим без const - "Вася" останется константным.
Прошу обратить внимание что это два объявления не эквивалентны что бы их сравнивать на лучше/хуже без учёта конкретного применения.
zltigo
Цитата(gotty @ Feb 24 2009, 15:50) *
Тут отличия гораздо глубже.

Разумеется. Речь идет о более-менее частном случае.
Цитата
то есть правильнее было бы
Код
const char *name = "Вася";
,

Вообще для полного целеуказания:
Код
char const * const name = "Вася";

Ну или соответственно специализированные квалификаторы для гарвардообразных
demiurg_spb
Цитата(gotty @ Feb 24 2009, 15:50) *
Тут отличия гораздо глубже.
Глубже-мельче...
В чистом виде (без static const) разница конкретная: в одном случае созаётся лишь массив, а в другом ещё и указатель на него. Вот и всё. Кому что нужно тот то и выбирает для себя. С константным указателем на константную строку наверняка могут быть варианты - будет зависеть от IQ компилятора.
west329_
Код
__flash  char test_[] = "hello";
char test_1[] = "test1 hello test2";


void test (void)
{
  char *p1, *p2, *p3;

  p1 = (char*)& test_[0];
  p2 =        & test_1[0];
  
  p3 = strstr( p2, p1);
}


Это бред ?
demiurg_spb
Цитата(west329_ @ Feb 24 2009, 17:14) *
Это бред ?
Вы на кофейной гуще гадаете что-ли? Документацию читали? Какие функции нашли? В отладчике (можно AVR-Studio) прогоняли? Какой компилятор? Делов на 20 минут. А вы... Ложку дай...
Файлик <pgmspace.h> смотрели - там все функции для работы с falsh.
west329_
Код
__x_z int strcatstrncmpstrncmp(const void *, PGM_VOID_P, size_t);
__x_z void *memcpy_P(void *, PGM_VOID_P, size_t);
__x_z char *strcat_P(char *, PGM_P);
__x_z int strcmp_P(const char *, PGM_P);
__x_z char *strcpy_P(char *, PGM_P);
__x_z char *strncat_P(char *, PGM_P, size_t);
__x_z int strncmp_P(const char *, PGM_P, size_t);
__x_z char *strncpy_P(char *, PGM_P, size_t)


Аналогично функции strstr, ненашол.
Копилятор IAR AVR CLIB
demiurg_spb
Цитата(west329_ @ Feb 25 2009, 09:12) *
Аналогично функции strstr, ненашол.
Копилятор IAR AVR CLIB
Вы Молодец. Теперь делаем вывод, что без дополнительных усилий Вашу задачу не решить.
Но есть очень простой способ (с использованием временного буфера - будет отъедать ОЗУ).
Пишите свою функцию, которая ищет в строке s1 (из ОЗУ) подстроку s2 (из flash)
Код
char* strstr_P(const char* s1, flash char* s2)
{
    #define MAX_STR_LEN    50            // допустим 50
    char buf[MAX_STR_LEN];
    strncpy_P(buf, s2, MAX_STR_LEN);     // копируем flash в buf
    buf[MAX_STR_LEN-1] = '\0';           // null в любом случае должен быть
    return  strstr(s1, buf);             // вызываем библиотечную функцию.
}

Вариант 2: пишите полностью с нуля функцию char* strstr_P(const char* s1, flash char* s2) без буферизации.
Вариант 3: отказываетесь от использования flash.
Всё в Ваших руках...
west329_
Всё работает как надо, благодарю за помощь. За ради интереса, собрал несколько аналогичных функций.
Код
char* strstr_P(const char* s1, flash char* s2)
{
    size_t len;
    len = strlen_P(s2);
    char *buf;  
    buf = malloc(len);
    strncpy_P(buf, s2, len);
    return  strstr(s1, buf);
}

самый прожорлевый вариант. прибавил сразу ~240kb
Код
char* strstr_P(const char* s1, flash char* s2)
{
    #define MAX_STR_LEN    30            // äîïóñòèì 30    
    char buf[MAX_STR_LEN];
    char len = strlen_P(s2);
    strncpy_P(buf, s2, len);     // êîïèðóåì flash â buf
    buf[len] = '\0';
   return  strstr(s1, buf)
}

немного меньше, но всёравно порядка 150кб
ваш код самый маленьки оказался, порядка 100кб
msalov
Цитата(west329_ @ Feb 25 2009, 12:20) *
Код
char* strstr_P(const char* s1, flash char* s2)
{
    #define MAX_STR_LEN    30
    char buf[MAX_STR_LEN];
    char len = strlen_P(s2);
    strncpy_P(buf, s2, len);
    buf[len] = '\0';
   return  strstr(s1, buf)
}

Советую не использовать этот вариант. Так как у вас тут потенциальное переполнение буфера. Безопасный вариант
Код
char* strstr_P(const char* s1, flash char* s2)
{
    #define MAX_STR_LEN    30
    char buf[MAX_STR_LEN];
    strncpy_P(buf, s2, MAX_STR_LEN);
    buf[MAX_STR_LEN - 1] = '\0';
   return  strstr(s1, buf);
}
demiurg_spb
Цитата(west329_ @ Feb 25 2009, 13:20) *
Всё работает как надо, благодарю за помощь. За ради интереса, собрал несколько аналогичных функций.
Эксперементировать надо с умом (простите, но гляда на то что Вы пишите у меня сердце кровью обливается).
Купите книжку по СИ и перечитайте её несколько раз - эти трудозатраты с лихвой окупятся.
Для общего развития:
1. На каждый malloc() должен быть свой free().
2. strncpy(s1,s2,n) копирует строку s2 в s1, но не более n символов, поэтому нас не интересует длина s2,
т.к. любая строка заканчивается '\0', а приёмный буфер (строка s1) имеет максимальную длину не меньше n.
И ещё, прикинте сколько машинных циклов добавят вызовы этих процедур: malloc() и free().
Да, можно еще немного оптимизировать:
Код
char* strstr_P(const char* s1, flash char* s2)
{
    #define MAX_STR_LEN    30
    char buf[MAX_STR_LEN];
    buf[MAX_STR_LEN - 1] = '\0';
    return  strstr(s1, strncpy_P(buf, s2, MAX_STR_LEN-1));
}
A. Fig Lee
то, что возвращает malloc() правильные пацаны проверяют на NULL.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.