字符处理的几个方法
/* *函数功能:从一段存放内存中读取某个字符第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; }