Перейти к содержанию
    

Как бы поработать со строками в KEIL так же как в С++ с Ansistring?

Есть буфер

uint8_t RX_BUF[256]

 

Хочу проверить не является ли содержимое буфера в позициях скажем 100-106 текстом "command"

 

Пока это сделано корявно

if ((RX_BUF[100]=='c') && (RX_BUF[101]=='o') && (RX_BUF[102]=='m') && (RX_BUF[103]=='m') && (RX_BUF[104]=='a') && (RX_BUF[105]=='n') && (RX_BUF[106]=='d'))
{
}

 

А хотелось бы что-то вроде

 

if (.......... =="command")

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

http://all-ht.ru/inf/prog/c/func/strncpy.html

 

Что-то я запуталась совсем в этом обилии...

 

Как бы вы наиболее рационально решили задачу:

В кольцевой буфер добавляются строки, каждый раз заканчивающиеся символом конца строки.

Грубо говоря, история команд, разделенная символами конца строки.

Нужно найти последнюю команду.

 

Ну например RX_BUF="command_1\0command_2\0command_3\0command_4\0command_5\0";

Нужно получить строку command_5...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что-то я запуталась совсем в этом обилии...

Для начала Вы не смогли даже осмыслить задачу хотя-бы "на пальцах" безотносительно к программированию. В изложенном виде

В кольцевой буфер добавляются строки, каждый раз заканчивающиеся символом конца строки.

Грубо говоря, история команд, разделенная символами конца строки.

Нужно найти последнюю команду.

задача решения не имеет вообще.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что использовать - зависит от "уровня" в чем Вы собираетесь использовать свою программу.

Если это приложение, которое будет "крутиться" в микроконтроллере

с ограниченными ресурсами (очень) - надо использовать вышеупомянутые strcmp(str1, sre2) и memcmp(str1, sre2, len).У

Если PC - MSVC - смотрите MFC, класс CString.

Там наверно в наличии == сравнение.

 

char MyRing[10][80];    // 10 строк-команд по 80 символов максим. каждая

MyRingControl CRing; // реализация управления кольц. буфером

CRing.AddCmd("Cls"); // пишем строку в MyRing[0], или по адресу &MyRing[0][0]
CRing.AddCmd("Dir"); // пишем строку в MyRing[1], или по адресу &MyRing[1][0]
CRing.AddCmd("Copy");// пишем строку в MyRing[2], или по адресу &MyRing[2][0]
CRing.AddCmd("Etc. . . ."); // . . . .
CRing.AddCmd("Exit");// пишем строку в MyRing[8], или по адресу &MyRing[8][0]

int LastCmdIdx = CRing.GetHead();    // в LastCmdIdx получаем 8 - послед. строка буфера

while(1)
{  
    . . . . 
    int result;
    . . . .
    result = strcmp( &MyRing[LastCmdIdx][0], "Exit" );
    if( result == 0 ) // (== Exit)
    {
       . . . .
    } 

    result = strcmp( &MyRing[LastCmdIdx][0], "Stop" );
    if( result == 0 ) // (== Stop)
    {
       . . . .
    } 
}
. . . .

Изменено пользователем k155la3

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как бы вы наиболее рационально решили задачу:

В кольцевой буфер добавляются строки, каждый раз заканчивающиеся символом конца строки.

Как Вам уже сказал zltigo, в такой постановке задачу не решить, а лично я поступил бы по читерски: положил бы рядом с буфером переменную, куда перед помещением строки в буфер складывал номер позиции, с которой начинается команда; или, если символы в буфер поступают по одному - помещать в эту переменную номер позиции символа '\0'

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Задача, естественно, имеет решение, потому что мы всегда знаем последнюю записанную позицию в кольцевом буфере. От которой легко можно найти все что заблагорассудится.

 

Как Вам уже сказал zltigo, в такой постановке задачу не решить, а лично я поступил бы по читерски: положил бы рядом с буфером переменную, куда перед помещением строки в буфер складывал номер позиции, с которой начинается команда; или, если символы в буфер поступают по одному - помещать в эту переменную номер позиции символа '\0'

А можно ли в принципе заполнять кольцевой буфер, не имея соответствующей переменной?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я уже сделала проще

 

if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET) 
  {
        USART_ClearITPendingBit(USART2, USART_IT_RXNE);

        
        usartData = USART_ReceiveData(USART2);    
            
            
            if (usartData == 0x0D) \\ когда приходит '\r'   переписываем содержимое в переменную хранящую последнюю команду и затираем буфер.
            {
                
                usart_buf[usart_bit++] = 0;  
                usart_bit=0;                 
                //--------------------------------------------------------------------------------------------------------------
                            
                for(t=0;t<32;t++) {USART_LAST_COMMAND[t]=usart_buf[t];}
                               //---------------------------------------------------------------------------------------------------------------
                usartData=0;  
                memset(usart_buf, 0, sizeof(usart_buf)); 
            }
            else 
            {
                usart_buf[usart_bit++] = usartData; 
                
            }    
        
  }

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Задача, естественно, имеет решение, потому что мы всегда знаем последнюю записанную позицию в кольцевом буфере.

Мы это Вы с murmur? Тогда так и пишите, потому, что ничего подобного ранее не было сообщено и более того все сказанное ранее не стыкуется с высказанной Вами гипотезой. Не говоря уже о том, что последняя записанная позиция не есть одно и тоже, что конец последней записанной команды.

А можно ли в принципе заполнять кольцевой буфер, не имея соответствующей переменной

Смотря что называть "переменной". Например, может быть аппаратная поддержка заполнения буфера.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я уже сделала проще

 

if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)
  {
        USART_ClearITPendingBit(USART2, USART_IT_RXNE);

        
        usartData = USART_ReceiveData(USART2);    
            
            
            if (usartData == 0x0D) \\ когда приходит '\r'   переписываем содержимое в переменную хранящую последнюю команду и затираем буфер.
            {
                
                usart_buf[usart_bit++] = 0;  -------------  А зачем здесь usart_bit++ если в следующей строке ОНО обнуляется ?
                usart_bit=0;                
                            
                for(t=0;t<32;t++) {USART_LAST_COMMAND[t]=usart_buf[t];} ----------- Если вводимая строка состоит из 1 символа - зачем 32 ?

                usartData=0;  ------------------------------- зачем ОНО, ведь до входа в if идет присваивание в ЕГО
                memset(usart_buf, 0, sizeof(usart_buf)); ------------ не имеет особого смысла
            }
            else
            {
                usart_buf[usart_bit++] = usartData;
                
            }    
        
  }

 

Что в постановке задачи есть необходимое условие,

байтовый кольцевой буфер, или кольцевой буфер вообще, или реализовать

аналог PC-консольной вывод истории комнад по <Ctrl>-E ?

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я уже сделала проще

..

usart_buf[usart_bit++] = usartData;

Нет проверки на переполнение буфера.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет проверки на переполнение буфера.

Задача устройства ждать нужную команду, поступающую с мобильного телефона по блютус, который до него пытается достучаться. А как достучится - буфер обнуляется.

Он и на буфер то не похож - каждая новая команда пишется в самое его начало.

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

 

Уже протестировала, работает как надо. Хочу перепрошивать по блютус. Сам перепрошивальщик по USART уже есть его работа проверена через USB-COM. Вот дорабатываю теперь под блютус.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Барышня, Вы значение слова "переполнение" понимаете? ;)

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Барышня, Вы значение слова "переполнение" понимаете? ;)

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

Барышня то понимает, что если буфер на 256 байт, и счетчик однобайтный, то проверка не нужна. А вод местным гуру похоже это не под силу ;)

 

Ка155ла3 со своими ошибочными наездами тоже как то неочень смотрится.

 

Неужели здесь вместо помощи новичкам имеет место банальная половая ревность? :)

Изменено пользователем bw429

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

если буфер на 256 байт, и счетчик однобайтный, то проверка не нужна.

Это плохой стиль - закладывать себе мины в исходниках.

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

Зато потом, если вдруг понадобится увеличить размер буфера, все будет работать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...