0D 0A 01 02 03 0D 0A 这是串口接到的帧我想用一段C++程序来找到帧头0D 0A帧尾OD 0A并确定数据长度
刚写了个函数,LZ看下满足需要不,呵呵,有问题再追问,全部代码:
#include <stdio.h>
#include <string.h>
//函数作用:从指定字符串里提取你要的数据
//参数说明:
//pSourc:源串指针
//pHeaderTail:起始和结尾标识字符,这里只能包含两个字符
//pResult:存放结果数据的指针
int ExtractData(const char *pSourc, const char *pHeaderTail, char *pResult)
{
//大概思路:遍历源串,查找开始和结束标记,并且记下两个位置
//遍历结束之后如果开始和结束标记都有,将数据拷贝到结果中
//两者少一,都认为是无效数据
if (pSourc == NULL || pHeaderTail == NULL)
{
return -1;
}
const char *pTmp = pSourc;
int iPointerIndex = 0;
int iFindHeader = 0;
int iFindTail = 0;
int iStartIndex = 0;
int iEndIndex = 0;
while(*pTmp != NULL)
{
//如果还没有找到起始标记,就查找起始标记
if (!iFindHeader)
{
if (*pTmp == *pHeaderTail)
{
if (*(pTmp + 1) != NULL && *(pTmp + 1) == *(pHeaderTail + 1))
{
//如果找到起始标记,记下位置
iFindHeader = 1;
iStartIndex = iPointerIndex + 2;//拷贝数据的时候从标记之后拷贝,所以加2
++iPointerIndex;
++pTmp;
continue;
}
}
}
//如果没有找到结束标记,查找结束标记
if (!iFindTail)
{
if (*pTmp == *pHeaderTail)
{
if (*(pTmp + 1) != NULL && *(pTmp + 1) == *(pHeaderTail + 1))
{
//找到,记下位置
iFindTail = 1;
iEndIndex = iPointerIndex;//用结束标记减开始标记再减1就是数据长度
++iPointerIndex;
++pTmp;
continue;
}
}
}
++iPointerIndex;
++pTmp;
}
//起始和结束标记都找到,拷贝数据
if (iFindHeader && iFindTail)
{
strncpy(pResult , pSourc + iStartIndex, iEndIndex - iStartIndex - 1);
return 0;
}
//否则,直接返回失败
return -1;
}
//以16进制形式输出数据
void OutPutHex(const char *pData)
{
int i = 0;
for (;i < strlen(pData); ++i)
{
printf("0x%02X ", pData[i]);
}
printf("\n");
}
int main()
{
int i = 0;
//保存结果数据的数组
char cResult[20] = {0};
//三组测试数据,注意要以\0结尾
char pSource[] = {0x0D,0x0A,0x01,0x02,0x03,0x04,0x0D,0x0A, 0x00};
char pSource1[] = {0x0D,0x0A,0x01,0x02,0x03,0x04,0x0D, 0x00};
char pSource2[] = {0x01,0x02,0x03,0x04,0x0D, 0x00};
//标记字符串,两个字符
char pHeaderTail[] = {0x0D,0x0A};
//开始测试
printf("Data is:\n");
OutPutHex(pSource);
if(0 == ExtractData(pSource, pHeaderTail, cResult))
{
printf("Result is:\n");
OutPutHex(cResult);
}
else
{
printf("Data is not complete.\n");
}
printf("Data is:\n");
OutPutHex(pSource1);
if(0 == ExtractData(pSource1, pHeaderTail, cResult))
{
printf("Result is:\n");
OutPutHex(cResult);
memset(cResult, 0 , 20);
}
else
{
printf("Data is not complete.\n");
}
printf("Data is:\n");
OutPutHex(pSource2);
if(0 == ExtractData(pSource2, pHeaderTail, cResult))
{
printf("Result is:\n");
OutPutHex(cResult);
memset(cResult, 0 , 20);
}
else
{
printf("Data is not complete.\n");
}
return 0;
}
结果截图:
谢谢您的回答,目前是利用串口接收数据,串口接收不是一次就能接收到一个整个的帧,每次接收到的字节数也是不同的,所以怎么样去确定这一个帧已经全部接收成功呢O(∩_∩)O谢谢
开始接收数据,每次收到数据就调用给你写的ExtractData函数,并判断返回值,如果返回0表示有头有尾,数据已经传完了,如果失败,就继续接收,把收到的数据追加到之前收到的数据后面,再调用ExtractData函数,直到函数调用成功为止。
你好,还得麻烦你一下,这个代码是不是在数据中有0的话就会在继续找了,假如我的数据是 0xff 0x3 0x20 0xad 0x0 0x36 0xa0 0x0 0x0 0x0 0x0 0x38 0xae 0x10 0x3 0xd 0xa 0x4f 0x4b 0xd 0xa 是不是找到第一个0x0就不会再找了,如果是这样改怎么解决啊谢谢了O(∩_∩)O