一、使用场景
栈是一种先入后出的数据结构,经常用于判断括号的有效性,另外对于需要多步骤解决的问题中,尤其是需要自下向上递归的得出结果时,栈通常用来存储上一步的结果、数据。
一些常见问题:
1. 判断括号有效性的问题
2. 在数据接收的问题中判断是否收到数据尾的时候,本次读取的数据要和前一次读取到数据最后几字节进行合并之后来判断是否读取到数据尾,使用栈这种先入后出的容器,可以方便对尾部元素进行操作。
bool CMCUBoard::readMCUBoard( std::vector<uint16_t> & vecReadData)
{
unsigned char table[8];
uint8_t buf[50];
memset(&buf[0], 0, 50);
int N = 0;
int tryNum = 6;
static int MCUBoardTryFlag = 0;
//1. 先读取数据头,确保读到协议头0xaa、0xaa、0xaa、0xaa,再读取剩余数据
do
{
//(1) 先读取1个字节,如果是0xaa则再读3字节,如果是0xaa,0xaa,0xaa则可判断读取到数据头
//如果不是0xaa,则丢弃
N = read( m_nFd, buf, 1 );
usleep(10000);
if (1 == N)
{
if ( 0xaa == buf[0] )
{
buf[0] = 0x00;
N = read( m_nFd, buf, 3 );
if (3 == N && 0xaa == buf[0] && 0xaa == buf[1] && 0xaa == buf[2] )
{
CRRC_DEBUG("read 0xaa 0xaa 0xaa 0xaa\n");
break;
}
}
else
{
//第一字节不aa
continue;
}
}
else
{
//未读取到数据
MCUBoardTryFlag ++;
if ( MCUBoardTryFlag > tryNum)
{
//resetPort();
CRRC_ERROR("MCUBoardTryFlag > tryNum");
MCUBoardTryFlag = 0;
return false;
}
continue;
}
}while(1);
//2. 再次循环读取,直至读取到协议尾部
N = 0;
//读取4字节放入栈中,先放4字节,再放1字节,每放一次则判断一次尾部,如果找到尾部则停止读取,获取到一帧数据
std::stack<uint8_t> stk;
std::vector<uint16_t> vecData;
N = read( m_nFd, &buf[0], 4 );
if(4 > N)
{
CRRC_ERROR("read error : "<<N);
return false;
}
if ( 0x55 == buf[0] && 0x55 == buf[1] && 0x55 == buf[2] && 0x55 == buf[3] )
{
CRRC_DEBUG("read 0x55 0x55 0x55 0x55");
return false;
}
stk.push(buf[0]);
vecData.push_back(buf[0]);
stk.push(buf[1]);
vecData.push_back(buf[1]);
stk.push(buf[2]);
vecData.push_back(buf[2]);
stk.push(buf[3]);
vecData.push_back(buf[3]);
tryNum = 6;
MCUBoardTryFlag = 0;
while(1)
{
buf[0] = 0x00;
if(1 > read( m_nFd, &buf[0], 1 ))
{
MCUBoardTryFlag ++;
if ( MCUBoardTryFlag > tryNum )
{
CRRC_ERROR(" MCUBoardTryFlag > tryNum ");
break;
}
else
{
continue;
}
}
else
{
stk.push(buf[0]);
vecData.push_back(buf[0]);
uint8_t flag1 = stk.top();
stk.pop();
uint8_t flag2 = stk.top();
stk.pop();
uint8_t flag3 = stk.top();
stk.pop();
uint8_t flag4 = stk.top();
stk.pop();
stk.push(flag4);
stk.push(flag3);
stk.push(flag2);
stk.push(flag1);
if ( 0x55 == flag1 && 0x55 == flag2 && 0x55 == flag3 && 0x55 == flag4 )
{
CRRC_INFO("read 0x55 0x55 0x55 0x55\n");
break;
}
}
}
//读完设剩余值
N = read( m_nFd, &buf[0], 50 );
#if 0
for (int i=0; i<vecData.size(); i++)
{
printf(" readMCUBoard [%d] : %02x ", i, vecData[i]);
printf(" \n");
}
printf(" \n");
#endif
vecReadData = vecData;
return true;
}