strstr可以用于在一个字符串中搜索另一个字符串,然而不适用于在环形表中搜索字符串。
字符串处理的几个方法介绍了一个在环形表中搜索字符串的代码,但经过测试,发现了1个bug,下面的代码已修复该bug(添加的3行语句见注释)
/*--------------------------------------------------------------------------------
*函数功能:从串口环形缓存区的新接收数据区域内搜索数组 是环形缓冲区
*输入参数:*p_bufhead:环形缓存区首地址
* bufSize: 缓存区大小
* *pos:搜索起始地址
* datalen: 搜索的数据块长度
* *searchArray:待搜索数组首地址
* searchLen: 待搜索数组长度
*返回参数:搜索成功,返回第一次出现该数组的首地址,如果搜索失败,返回NULL
*函数说明:
*--------------------------------------------------------------------------------*/
uint8_t* SearchnDataFromCycbuf(uint8_t* p_bufhead,uint16_t bufSize,uint8_t* pos,uint16_t datalen,uint8_t* searchArray,uint16_t searchLen)
{
uint16_t dataLen_Tmp = datalen;
uint8_t* pos1 = pos;
uint16_t sLen = searchLen;
uint8_t* pos2 = searchArray;
uint8_t* pos3 =NULL;
if((p_bufhead== NULL)||(searchArray == NULL)||(searchLen >datalen)||(pos<p_bufhead))
return NULL;
while(dataLen_Tmp >0)
{
if(*pos1 == *pos2)
{
if(pos3 == NULL)
pos3 = pos1;
pos2++;
sLen--;
if(sLen == 0)
return pos3;
}
else
{
if(pos3 != NULL) // 添加的代码
{ // 添加的代码
pos1--; // 添加的代码
dataLen_Tmp++; // 添加的代码
} // 添加的代码
pos3 = NULL;
pos2 = searchArray;
sLen = searchLen;
}
pos1++;
if(pos1 > p_bufhead+bufSize-1) //循环折回
pos1 = p_bufhead;
dataLen_Tmp--;
}
return NULL;
}
这个bug是:如果要查找的字符串是ab,而环形表中从读指针指向位置开始的内容依次是aabcdef,从读指针位置开始查找,那么会找不到。因为:在pos1指向第2个a、pos2指向b时,对比不匹配,pos2重新指向a,而pos1会加1,从而指向b,这样就跳过了第2个a开始的ab。
分析这个问题:如果已经发生过匹配,即pos3已被赋值,而当前的对比不匹配时,pos1不应加1,应该从当前pos1开始重新对比。因此,解决方法是:当pos3已被赋值时,pos1先减1,这样就与pos1加1抵消了,相当于没有加1。注意:pos1减1时,dataLen_Tmp也要加1。
上述提出的方法只适用于查找的字符串只包含2个字符的情况。如果多于2个字符,则添加的代码应修改。修改的大致思路是:一旦匹配不成功,则pos1被赋值为pos3+1,注意dataLen_Tmp也要做相应调整。