我试图通过strstr()函数检查子串(" DATA")是否(及其位置)位于一个大字符串(位于缓冲区 - linearBuffer中),但它似乎不起作用,我不知道为什么我的源字符串(位于linearBuffer中)以null结束。
真正的问题是,每个USART中断都会有一个环形缓冲区(buf)填充字符。然后,在代码的某个点上,将其内容复制到线性缓冲区(通过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
}
}
}
}
答案 0 :(得分:1)
当 <tbody>
<% @tasks.each do |task| %>
<tr>
<td><%= task.title %></td>
<td><%= task.note %></td>
<td><%= task.created_at.strftime("%A,%B,%Y") %></td>
</tr>
<% end %> #this ends the @task.each do loop
</tbody>
</table>
<% end %> #this ends the if else conditional
返回NULL时,意味着它没有找到子字符串(当发生这种情况时,它指向的值根本没有意义,所以忘掉224)。
所以你的问题应该是:
为什么strstr找不到我的子串?
查看您发布的调试图片时,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
(索引[1])时,它会返回0
,因为它找不到它要查找的内容。
换句话说 - NULL
永远不会查看匹配所在的缓冲区部分。它在此之前就已经很久了。
你的代码出了什么问题?
由于您尚未发布完整的代码库,因此很难说。所以这是猜测。我认为你会收到一些形式的“换行符”:
strstr
之前的消息。所以你收到了:
13 10 13 10
您的ISR将13 10 13 10 43 ...... 68 65 .....
转换为10
,因此缓冲区变为
0
这是3个字符串而不是1个字符串。
怎么办?
嗯,可能有几种不同的解决方案。正确取决于您的系统要求。一个简单的解决方案是在调用13 0 13 0 43 ...... 68 65 .....
之前跳过额外的13 0
。类似的东西:
strstr
注意:您还应该添加一些范围检查,以便ringBuff_to_linearBuff(linearBuffer);
// Skip "13 0"
while (*linearBuffer == 13 && *(linearBuffer+1) == 0)
{
linearBuffer += 2;
}
linearBufferp = strstr(linearBuffer, WIFI_CMD_DATA);
不会增加太多以至于您读出界限