字符处理的几个方法
/*
*函数功能:从一段存放内存中读取某个字符第count次出现的地址 并返回
*输入参数:*pHead:待查找起始地址
len:待查找内存块长度
*Delim: 待查证的字符
count: 第count次出现
返回值:NULL:读取失败; 有效地址:读取成功
*/
uint8_t *GetDelimAddFromStrBuf(uint8_t* pdata,uint16_t len,char Delim,uint16_t count)
{
uint8_t ui8len = len;
uint16_t counter = 0;
uint8_t* pos = pdata;
if((pos == NULL)||(count > ui8len)||(pos >= (pdata+len))) return NULL;
while(ui8len--)
{
if(*pos == Delim)
{
counter++;
if(counter == count) return pos;
}
pos++;
}
return NULL;
}
/*
*函数功能:从一段存放内存中读取某个字符第count次出现的地址 并返回
*输入参数:*pdatahead: 待查找起始地址
pdatatail:待查找结束地址
*Delim: 待查证的字符
count: 第count次出现
返回值:NULL:读取失败; 有效地址:读取成功
*/
uint8_t *GetDelimAddFromStrBufpt(uint8_t* pdatahead,uint8_t* pdatatail,char Delim,uint16_t count)
{
uint16_t counter = 0;
uint8_t* headpos = pdatahead;
uint8_t* tailpos = pdatatail;
if((headpos == NULL)||(tailpos == NULL)||(headpos > tailpos)) return NULL;
if (count == 0) return pdatahead;
while(headpos<=tailpos)
{
if(*headpos == Delim)
{
counter++;
if(counter == count) return headpos;
}
headpos++;
}
return NULL;
}
/*--------------------------------------------------------------------------------
*函数功能:从串口缓存区的新接收数据区域内搜索数组 不是环形缓冲区
*输入参数:*p_bufhead:环形缓存区首地址
* bufSize: 缓存区大小
* *pos:搜索起始地址
* datalen: 搜索的数据块长度
* *searchArray:待搜索数组首地址
* searchLen: 待搜索数组长度
*返回参数:搜索成功,返回第一次出现该数组的首地址,如果搜索失败,返回NULL
*函数说明:
*--------------------------------------------------------------------------------*/
uint8_t* SearchnDataFromBuf(uint8_t* srcBuf,uint16_t srcSize,uint8_t* data,uint16_t datalen)
{
uint16_t dataLen_Tmp = datalen;
uint8_t* pos = srcBuf;
uint16_t sSize = srcSize;
if((srcBuf== NULL)||(data == NULL)||(srcSize <datalen))
return NULL;
while(sSize >=dataLen_Tmp)
{
if(*pos == *data)
{
if(memcmp(pos,data,dataLen_Tmp) == 0)
return pos;
}
pos++;
sSize--;
}
return NULL;
}
/*--------------------------------------------------------------------------------
*函数功能:从串口环形缓存区的新接收数据区域内搜索数组 是环形缓冲区
*输入参数:*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
{
pos3 = NULL;
pos2 = searchArray;
sLen = searchLen;
}
pos1++;
if(pos1 > p_bufhead+bufSize-1) //循环折回
pos1 = p_bufhead;
dataLen_Tmp--;
}
return NULL;
}
/*--------------------------------------------------------------------------------
*函数功能:从串口环形缓存区的新接收数据区域内搜索数组
*输入参数:*p_bufhead:环形缓存区首地址
* bufSize: 缓存区大小
* *p_head:搜索起始地址
* *p_tail: 搜索结束地址
* *searchArray:待搜索数组首地址
* searchLen: 待搜索数组长度
*返回参数:搜索成功,返回第一次出现该数组的首地址,如果搜索失败,返回NULL
*函数说明:
*--------------------------------------------------------------------------------*/
uint8_t* SearchnDataFromCycbufByPoint(uint8_t* p_bufhead,uint16_t bufSize,uint8_t* p_head,uint8_t* p_tail,uint8_t* searchArray,uint16_t searchLen)
{
uint16_t dataLen_Tmp;
if((p_bufhead== NULL)||(searchArray == NULL)||(p_head<p_bufhead)||(p_tail<p_bufhead))
return NULL;
if(p_tail > p_head)
dataLen_Tmp = p_tail- p_head;
else
dataLen_Tmp = bufSize - (p_head - p_tail);
return SearchnDataFromCycbuf(p_bufhead, bufSize,p_head,dataLen_Tmp,searchArray,searchLen);
}
/*----------------------------------------------------------------------------------------*
*函数功能: 设置环形缓存区里面的部分数据
*输入参数: *p_bufhead:循环缓存区的头文件
bufSize:循环缓存区的大小
*pos:待清除数据块的首地址
datalen:待清除数据长度
flag:待设置的内容
*返回值: 0:清除成功 ;-1:清除失败
*-----------------------------------------------------------------------------------------*/
int8_t MemsetToCycbuf(uint8_t* p_bufhead,uint16_t bufSize,uint8_t* pos,uint16_t datalen,uint8_t flag)
{
uint16_t dataLen_Tmp = datalen;
uint8_t* pos1 = pos;
if((p_bufhead== NULL)||(datalen >bufSize)||(pos<p_bufhead)||(pos >p_bufhead+ bufSize-1))
return -1;
while(dataLen_Tmp >0)
{
*pos1++ = flag;
if(pos1 > p_bufhead+bufSize-1) //循环折回
pos1 = p_bufhead;
dataLen_Tmp--;
}
return 0;
}
/*----------------------------------------------------------------------------------------*
*函数功能:清零环形缓存区里面的部分数据
*输入参数:*p_bufhead:循环缓存区的头文件
* bufSize:循环缓存区的大小
* *pos:待清除数据块的首地址
* datalen:待清除数据长度
*返回值: 0:清除成功 ;-1:清除失败
*-----------------------------------------------------------------------------------------*/
int8_t MemsetToCycbufByPoint(uint8_t* p_bufhead,uint16_t bufSize,uint8_t* p_Head,uint8_t* p_Tail,uint8_t flag)
{
uint16_t dataLen_Tmp ;
//指针有效性检测
if((p_bufhead== NULL)||(p_Head<p_bufhead)||(p_Head >p_bufhead+ bufSize-1)||(p_Tail<p_bufhead)||(p_Tail >p_bufhead+ bufSize-1))
return -1;
if(p_Head < p_Tail)
dataLen_Tmp = p_Tail - p_Head;
else
dataLen_Tmp = bufSize-(p_Head - p_Tail);
return MemsetToCycbuf(p_bufhead, bufSize,p_Head,dataLen_Tmp,flag);
}
/*--------------------------------------------------------------------------------------
*函数功能:重新定位循环缓存区的指针
*输入参数:*p_bufhead:循环缓存区头指针
* bufSize:循环缓存区大小
* *pos:当前数据指针
* shiftsize:移动字节数
* flag:0:向右移动;1:向左移动
*返回参数:新位置
*
*-------------------------------------------------------------------------------------*/
uint8_t* llseekToCycbuf(uint8_t* p_bufhead,uint16_t bufSize,uint8_t* pos,uint16_t shiftsize,uint8_t flag)
{
uint16_t shiftBytes = shiftsize;
uint8_t* pos1 = pos;
if((p_bufhead== NULL)||(pos<p_bufhead)||(pos >p_bufhead+ bufSize-1))
return NULL;
if(flag == 0)//向右移动指针
{
pos1 = pos1+shiftsize;
while(1)
{
if(pos1 > p_bufhead+bufSize-1) //循环折回
pos1 = (uint8_t*)(pos1 - bufSize);
else
break;
}
}
else if(flag == 1)//向左移动指针
{
while(shiftBytes--)
{
pos1--;
if(pos1 < p_bufhead)
pos1 = p_bufhead+bufSize-1;
}
}
return pos1;
}
/*--------------------------------------------------------------------------------
*函数功能:通过待读取收尾指针从串口环形缓存区中读取一帧数据
*输入参数:*p_bufhead:环形缓存区首地址
* bufSize: 缓存区大小
* *p_readhead:读取数据块的头地址
* *p_readtail:读取数据块的尾地址
* *buf:读取数据存放的位置地址
* bufSize:存放读取数据的内存块大小
* *pLen:读取数据长度存放地址
*返回参数:0:读取数据成功 ;-1:指针地址无效;-2:分配内存不够
*函数说明:读取首地址跟尾地址之间的数据段,不包含首尾地址
*--------------------------------------------------------------------------------*/
int8_t ReadDataFromCycbufByPoint(uint8_t* p_bufhead,uint16_t bufSize,uint8_t* p_readhead,uint8_t* p_readtail,uint8_t* desBuf,uint16_t desSize,uint16_t *pLen)
{
uint16_t readBytes;
uint8_t* pRead = p_readhead;
if((p_bufhead== NULL)||(p_readhead == NULL)||(p_readtail == NULL))
return -1;
if( p_readtail<= p_readhead)
readBytes = bufSize - (p_readhead-p_readtail)-1;//写指针不能跟读指针重合
else
readBytes =p_readtail-p_readhead-1;
if(readBytes > desSize)//存储空间不够
return -2;
pRead++;//去掉读取首地址中的数据
if(pRead > p_bufhead+bufSize-1)
pRead = p_bufhead;
while(readBytes--)
{
*desBuf++ = *pRead++;
if(pRead > p_bufhead+bufSize-1)
pRead = p_bufhead;
(*pLen)++;
}
return 0;
}
/*--------------------------------------------------------------------------------
*函数功能:通过待读取数据长度从串口环形缓存区中读取一帧数据
*输入参数:*p_bufhead:环形缓存区首地址
* bufSize: 缓存区大小
* *p_readhead:读取数据块的头地址
* readlen:读取数据块的长度
* *buf:读取数据存放的位置地址
* bufSize:存放读取数据的内存块大小
*返回参数:0:读取数据成功 ;-1:指针地址无效;-2:分配内存不够
*函数说明:
*--------------------------------------------------------------------------------*/
int8_t ReadDataFromCycbufByLen(uint8_t* p_bufhead,uint16_t bufSize,uint8_t* p_readhead,uint16_t readLen,uint8_t* desBuf,uint16_t desSize)
{
uint16_t readBytes ;
uint8_t* pRead = p_readhead;
int8_t result = 0;
if((p_bufhead== NULL)||(p_readhead == NULL))
return -1;
if(readLen > desSize)//存储空间不够
{
readBytes = desSize;
result = -2;
}
else
{
readBytes = readLen;
}
while(readBytes--)
{
*desBuf++ = *pRead++;
if(pRead > p_bufhead+bufSize-1)
pRead = p_bufhead;
}
return result;
}