Jump to content

    

процедура с указателем на строку в памяти программ

Здраствуйте. Ткните где не так кто знает пожалуйста

unsigned char blabla[] = "blablabla";
/// текст и все такое
void find (unsigned char *findbuff)
{
    unsigned int i;
    while (*findbuff != '\0')
   {
    USART0_OutBuf[i++] = *findbuff;
    findbuff++;
   }
}
int main (void)
{
find (blabla);
}

т.е. программа какие то данные из ОЗУ грузит в процедуру и что то так с ними делает

Скажите пожалуйста как такое же провернуть со строкой типа

unsigned char PROGMEM blabla[] = "blablabla";

Спасибо

Share this post


Link to post
Share on other sites

И что ты хочешь найти? :)

Если ты хочешь найти строку в "блабла" в буфере... - тогда тебе надо цикл опирать на буфер а не на строку.

Share this post


Link to post
Share on other sites
Скажите пожалуйста как такое же провернуть со строкой типа
unsigned char PROGMEM blabla[] = "blablabla";

Во-первых, строка должна заканчиваться завершающим нулем.

unsigned char PROGMEM blabla[] = "blablabla\0";

А во-вторых, перед выводом нужно указателю присвоить значение ее адреса, явно сделав преобразование типа.

findbuff=(unsigned char *)&blabla[0];

Share this post


Link to post
Share on other sites

дело в том что я хочу каждый раз используя одну и ту же функцию искать разные строки подгружаемые из памяти программ. Функция ищет данные из FLASH в буфере UART. И если находит то сообщает об этом. Если считать данные одной функцией и потом сравнить два буффера то все получается. Проблема в том что я не знаю как объявить стоку из FLASH и затем данные из этой строки использовать в функции.

Share this post


Link to post
Share on other sites
Проблема в том что я не знаю как объявить стоку из FLASH и затем данные из этой строки использовать в функции.

Почитайте вот эту тему

http://electronix.ru/forum/index.php?showtopic=56157&hl=

может натолкнет на идеи.

Share this post


Link to post
Share on other sites

Я решал вашу задачу так:

flash char *flash STRING_COMPARE[]={"BLA-BLA-BLA", "LY-LY-LY"};

char* COMPARE_STRING_RX(flash char *ptr_to_compare_rx) //не равны-возращается указательна NULL   
                                       {    
                        char*  ptr;                                                                    
    return ptr=strstrf(str_rx,ptr_to_compare_rx);    //str_rx-строка в ОЗУ,где лежат 
                                                                         //принятые данные от модема                               
                                       }                                
Где-то в коде:
if(COMPARE_STRING_RX(ptr_to_compare_rx=STRING_COMPARE[3]))// что-то делаем если cтрока совпала
else                         //делаем что-то другое-строка не совпала

это для CVAVR.

Share this post


Link to post
Share on other sites

в вашем случае насколько я понял сравниваются строки полностью. Я же во всем буффере ищу конкретное слово. На деле у меня это работает так. Копирую данные из флеш в буффер1 и ищу последовательность в буффере2. Но для этого приходится использовать две функции

кстати я уже получил ответ на свой вопрос. может кому пригодится. Все оказалось как всегда просто

const unsigned char PROGMEM blabla[] = "blablabla"; 

void find (const unsigned char *findbuff){ 
    unsigned int i=0; 
    unsigned char temp; 
    while(1){ 
        temp = pgm_read_byte(findbuff++); 
        if(temp==0) break; 
        USART0_OutBuf[i++] = temp; 
    } 
} 
int main (void){ 
    find (blabla); 
}

Edited by chief_olimp

Share this post


Link to post
Share on other sites
Во-первых, строка должна заканчиваться завершающим нулем.

unsigned char PROGMEM blabla[] = "blablabla\0";

А во-вторых, перед выводом нужно указателю присвоить значение ее адреса, явно сделав преобразование типа.

findbuff=(unsigned char *)&blabla[0];

Ни во-первых ни во-вторых делать не надо.

Все СИ строки имеют завершающий ноль по определению.

Имя одномерного масссива также является указателем на его первый элемент, так зачем же плодить промежуточные переменные.

Приводить тип не надо, а надо использовать тип char для строк и char* для аргумента функции (ну или const char как в данном случае).

На мой взгляд unsigned char следует использовать только как альтернативу uint8_t, а элементы строк, т.е. буквы-символы в подавляющем большинстве имеют тип char, на то он и нужен.

Share this post


Link to post
Share on other sites

#define Str const unsigned char PROGMEM
Str blabla[] = "blablabla";
Str bububu[] = "bububu(b)";
Str *all_strings[3]={&blabla, &bububu,NULL};

unsigned char find (const unsigned char *findbuff){ 
    unsigned int i=0; 
    unsigned char temp; 
    unsigned char *pos=&USART0_OutBuf[0];
    while(i < sizeof(USART0_OutBuf))
    { 
        temp = pgm_read_byte(findbuff++); 
        if(temp==0) return 1; // found the full string substitution 
        if(*pos++ != temp) break; 
        i++;
    } 
  return(0);// not found
}

Так, что ли ?

Share this post


Link to post
Share on other sites

2chief_olimp : простите. но то что вы написали - это не find ... это strcpy() причем в извращенной форме.

при чем тут find? если он ничего не возвращет и не сообщает?

 

2pasha: а если строка не с начала? :)

Edited by rokhan

Share this post


Link to post
Share on other sites
#define Str const unsigned char PROGMEM
Str blabla[] = "blablabla";
Str bububu[] = "bububu(b)";
Str *all_strings[3]={&blabla, &bububu,NULL};

unsigned char find (const unsigned char *findbuff){ 
    unsigned int i=0; 
    unsigned char temp; 
    unsigned char *pos=&USART0_OutBuf[0];
    while(i < sizeof(USART0_OutBuf))
    { 
        temp = pgm_read_byte(findbuff++); 
        if(temp==0) return 1; // found the full string substitution 
        if(*pos++ != temp) break; 
        i++;
    } 
  return(0);// not found
}

Так, что ли ?

Похоже что не так.

Str *all_strings[3]={blabla, bububu,NULL};
или
Str *all_strings[3]={&blabla[0], &bububu[0],NULL};

Share this post


Link to post
Share on other sites
Похоже что не так.

Точно! (AVR-libc в помощь). спасибо.

 

2pasha: а если строка не с начала? :)

тогда считать кол-во совпавших символов и принимать решение исходя из этого.

Share this post


Link to post
Share on other sites
Ни во-первых ни во-вторых делать не надо.

Все СИ строки имеют завершающий ноль по определению.

Имя одномерного масссива также является указателем на его первый элемент, так зачем же плодить промежуточные переменные.

Приводить тип не надо, а надо использовать тип char для строк и char* для аргумента функции (ну или const char как в данном случае).

На мой взгляд unsigned char следует использовать только как альтернативу uint8_t, а элементы строк, т.е. буквы-символы в подавляющем большинстве имеют тип char, на то он и нужен.

Теоретически вы правы. На практике могут проявиться нюансы. Как-то, приведение типа указателя без операции извлечения адреса не работает. А приведение типа в данном случае необходимо, т.к. указатель и массив имеют разный тип. IAR, например, сругался бы без приведения типа. Насчет char и unsigned char нужно опять же смотреть опции компилятора. Либо твердо помнить, что в строковых переменных используем только KOI-7 и/или только латиницу.

Share this post


Link to post
Share on other sites
в вашем случае насколько я понял сравниваются строки полностью. Я же во всем буффере ищу конкретное слово.

ничего подобного-ищется конкретная лексема в строке.вы,имхо,делаете лишнюю работу,причем 2 раза.

1-зачем-то копируете лексему для поиска из флеш в озу.Нафига?

2-зачем вообще изобретать велосипед-все придумано до нас(с)-стандартная библиотека функций Си.

Почитайте про функцию strstr из стандартной библиотеки,файл string.h.Единственно,вам нужен вам нужен вариант для нахождения в строке,лежащей в озу подстроки,находящейся во флеш.Покурите на эту тему хэлп вашего компилятора.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this