2016-04-30 5 views
-2

Я пытаюсь проверить, будет ли (и где) подстрока («DATA») расположена в большой строке (расположенной в буфере - linearBuffer) функцией strstr(), но он, похоже, не работает, и я не знаю, почему, хотя моя исходная строка (находящаяся в линейном буфере) в нулевом завершении.Функция strstr() возвращает адрес 0x0000

Что действительно произошло, так это то, что ringbuffer (buf) заполняется символами для каждого прерывания USART. Затем в некоторой точке кода его содержимое копируется в линейный буфер (через ringBuff_to_linearBuff()), и я применяю на нем функцию strstr(), чтобы найти нужную подстроку. Значение, которое я получаю, когда функция strstr() возвращает значение 244, а не местоположение события подстроки, хотя я знаю его там от установки точки останова

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

#include <string.h> 

#define BUFFER_SIZE   400 
#define LINEAR_BUFFER_SIZE (BUFFER_SIZE+1) 
#define WIFI_CMD_DATA "DATA" 

typedef RingBuff_Data_t  uint8_t; 

typedef struct 
{ 
    RingBuff_Data_t Buffer[BUFFER_SIZE]; /**< Internal ring buffer data, referenced by the buffer pointers. */ 
    RingBuff_Data_t* In; /**< Current storage location in the circular buffer */ 
    RingBuff_Data_t* Out; /**< Current retrieval location in the circular buffer */ 
} RingBuff_t; 

volatile RingBuff_t buf; 
uint8_t linearBuffer[LINEAR_BUFFER_SIZE]=""; 

static inline void RingBuffer_Insert(RingBuff_t* const Buffer, const RingBuff_Data_t Data) 
{ 
    *Buffer->In = Data; 

    if (++Buffer->In == &Buffer->Buffer[BUFFER_SIZE]) 
       Buffer->In = Buffer->Buffer; 

    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 
    { 
     Buffer->Count++; 
    } 
} 

ISR(USART1_RX_vect) 
{ 
    //code to be executed when the rx pin of the USART receives a char 
    uint8_t c = UDR_N; 
    if (c != '\n') 
     RingBuffer_Insert(&buf,c); 
    else 
     RingBuffer_Insert(&buf,'\0'); 
} 

void ringBuff_to_linearBuff(uint8_t linearBuffer[]) 
{ 
    memset(linearBuffer,0,LINEAR_BUFFER_SIZE); 
    RingBuff_Data_t* tempIn = buf.In; 
    if (buf.Out < tempIn){ 
     memcpy(linearBuffer, buf.Out, tempIn - buf.Out); 
    } 
    else if (buf.Out > tempIn){ 
     size_t s1 = buf.Buffer + BUFFER_SIZE - buf.Out; 
     size_t s2 = buf.In - buf.Buffer; 
     memcpy(linearBuffer, buf.Out, s1); 
     memcpy(linearBuffer + s1, buf.Buffer, s2); 
    } 
} 

void main() 
{ 
    uint8_t* linearBufferp; 
    while (1) 
    { 
     if (buf.Out != buf.In) 
     { 
      ringBuff_to_linearBuff(linearBuffer); 
      linearBufferp = strstr(linearBuffer, WIFI_CMD_DATA); // Checking if a new DATA msg from a client had arrived 
      if (linearBufferp != NULL) 
      { 
       //do something 
      } 
     } 
    } 
} 

debugging

+1

Почему вы используете 'uint8_t' массив для хранения строк? Во всяком случае, было бы лучше добавить 'printf («% s \ n », linearBuffer);' перед вызовом 'strstr', чтобы мы могли убедиться, что он есть. – fluter

+0

Нам сложно помочь, так как код неполный. Например, мы не знаем, правильно ли инициализированы 'Buffer-> In' и' Buffer-> Out'. И мы не знаем призов 'ISR' и действительно ли это завершено завершение NUL до вызова ringBuff_to_linearBuff'. – kaylum

+0

Что такое 'linearBufferp'? – alk

ответ

1

Когда strstr возвращает NULL это означает, что он не нашел подстроку (и когда это произойдет, то его значение указывает, не имеют никакого значения, так что забудьте о 224).

Так что ваш вопрос должен быть:

Почему не strstr найти мой подстроку?

При взгляде на отладочный картинке вы в курсе, ваш linearBuffer содержит:

13 
0 
13 
0 
43 
.... 
.... 
68  <---- This is what you want to find 
65 
.... 

Однако, есть несколько строк в буфере:

13  <----- Start of first string 
0  <----- End of first string 
13  <----- Start of second string 
0  <----- End of second string 
43  <----- Start of thrid string 
.... 
.... 
68  <---- This is what you want to find 
65 
.... 

strstr только поиск первой строки , Когда strstr видит первый 0 (индекс [1]), он возвращает NULL, потому что он не нашел то, что искал.

Иными словами - strstr никогда не смотрит на ту часть буфера, где находится совпадение. Он возвращается задолго до этого.

Так что случилось с кодом?

Сложно сказать, так как вы не разместили полную базу кода. Так что это предположение. Я думаю, что вы получаете ряд «новых линий» в форме:

перед сообщением. Таким образом, вы получите:

13 10 13 10 43 ...... 68 65 ..... 

Ваш ISR превращает 10 в 0 поэтому буфер становится

13 0 13 0 43 ...... 68 65 ..... 

, который составляет 3 строки вместо 1 строки.

Что делать?

Ну, может быть несколько различных решений. Правильно зависит от ваших системных требований. Простым решением было бы пропустить дополнительный 13 0 перед вызовом strstr. Что-то вроде:

ringBuff_to_linearBuff(linearBuffer); 
// Skip "13 0" 
while (*linearBuffer == 13 && *(linearBuffer+1) == 0) 
{ 
    linearBuffer += 2; 
} 
linearBufferp = strstr(linearBuffer, WIFI_CMD_DATA); 

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

+0

Большое спасибо! Ты совершенно прав! – Prince777

Смежные вопросы