最近项目里一个问题要用到容器存储数据,因为C++的stl容器在MFC中不能用,因为会引起运算符重载,所以只能用MFC中的CList容器,但是csdn上的CList博客都是抄来抄去,也没有具体的用法实例,太恶心了,自己折腾了半天才找到遍历CList容器的方法;
1.CList容器基本操作:
标题/末尾访问
GetHead 返回列表的标题元素(不能为空)
GetTail 返回列表的末尾元素(不能为空)
操作
RemoveHead 从列表标题中移走元素
RemoveTail 从列表末尾移走元素
AddHead 添加一个元素(或另一个列表的所有元素)到列表标题(生成新的标题)
AddTail 添加一个元素(或另一个列表的所有元素)到列表尾部(生成新的尾部)
RemoveAll 从列表中移走所有元素
循环
GetHeadPosition 返回列表标题元素的位置
GetTailPosition 返回列表尾部元素的位置
GetNext 先返回本位置的元素,然后位置指针指向后一个元素
GetPrev 先返回本位置的元素,然后位置指针指向前一个元素
获取/修改
GetAt 在指定位置上获得元素
SetAt 在指定位置上设置元素
RemoveAt 从列表中删除一个由位置确定的元素
插入
InsertBefore 在指定位置前插入一个新的元素
InsertAfter 在指定位置后插入一个新的元素
查找
Find 获得由指针值确定的元素位置
FindIndex 获得由基于零的索引指定的元素位置
状态
GetCount 返回此列表中的元素数
IsEmpty 检测空列表的情况(没有元素)
2.遍历CList容器实例
(1)for循环遍历元素(第一种方法)
CList<int> mList;
POSITION posi; /*不能像数组一样用下标遍历CList容器,必须用POSITION变量表示位置*/
CString str;
for (int i = 0; i < 5; i ++)
{
mList.AddTail(i);/*从尾部插入数据*/
}
/*CList容器获取尾部指针的函数是获取最后一个元素的位置,
而不是跟STL容器一样得到最后一个元素后面的位置,
所以在循环中不能用posi != mList.GetTailPosition()作为判断条件,会导致最后一个数据无法读取
*/
for (posi = mList.GetHeadPosition(); posi != NULL; mList.GetNext(posi))
{
/*GetAt()中的参数必须是POSITION变量,用0, 1之类的整数下标是不行的*/
str.AppendFormat(_T("%d "), mList.GetAt(posi));
}
(2)while循环遍历元素(第二种方法)
CList<int> mList;
POSITION posi; /*不能像数组一样用下标遍历CList容器,必须用POSITION变量表示位置*/
CString str;
for (int i = 0; i < 5; i ++)
{
mList.AddTail(i);
}
/*CList容器获取尾部指针的函数是获取最后一个元素的位置,
而不是跟STL容器一样得到最后一个元素后面的位置,
所以在循环中不能用posi != mList.GetTailPosition()作为判断条件,会导致最后一个数据无法读取
*/
posi = mList.GetHeadPosition();
while(posi != NULL)
{
/*GetNext函数先返回当前位置的值,位置指针再指向后一个元素*/
str.AppendFormat(_T("%d "), mList.GetNext(posi));
}
(3)while循环遍历元素(第三种方法)
CList<int> mList;
POSITION posi; /*不能像数组一样用下标遍历CList容器,必须用POSITION变量表示位置*/
CString str;
for (int i = 0; i < 5; i ++)
{
mList.AddTail(i);
}
/*CList容器获取尾部指针的函数是获取最后一个元素的位置,
而不是跟STL容器一样得到最后一个元素后面的位置,
所以在循环中不能用posi != mList.GetTailPosition()作为判断条件,会导致最后一个数据无法读取
*/
posi = mList.GetHeadPosition();
while(posi != NULL)
{
/*跟第二种方法差不多*/
str.AppendFormat(_T("%d "), mList.GetAt(posi));
mList.GetNext(posi);
}
AfxMessageBox(str);
3.项目里用到CList的地方
有个地方会收到如下报文内容:
/*(1) 先定义一个结构体,同时包含SV和SNR两个数据*/
typedef struct _Signal
{
int svSignal;
int snrSignal;
}mSignal;
/*(2) 信号读取函数代码*/
BOOL GetAllSignal(CList<mSignal>& sig, char* recvMsg)
{
if(recvMsg == NULL || !(strstr(recvMsg, "SV")) || !(strstr(recvMsg, "SNR")) || !(strstr(recvMsg, ":")))
{
return FALSE;
}
BOOL bRet = TRUE;
char getSig[50] = {0};
int i = 0;
mSignal tempSig;
while (*(recvMsg++) != '\0')
{
/*每一条报文都是先找到SV字符的位置,并读取值*/
if((recvMsg = strstr(recvMsg, "SV")) == NULL)
{
break;
}
//cout << recvMsg << endl;
while (*recvMsg != '\0' && !(*recvMsg >= '0' && *recvMsg <= '9')) recvMsg++;
while((*recvMsg != '\0') && (*recvMsg >= '0' && *recvMsg <= '9'))
{
getSig[i++] = *recvMsg;
recvMsg++;
}
i = 0;
tempSig.svSignal = atoi(getSig);
memset(getSig, '\0', sizeof(getSig));
/*找到SNR字符的位置,并读取值*/
if((recvMsg = strstr(recvMsg, "SNR")) == NULL)
{
break;
}
//cout << recvMsg << endl;
while (*recvMsg != '\0' && !(*recvMsg >= '0' && *recvMsg <= '9')) recvMsg++;
while((*recvMsg != '\0') && (*recvMsg >= '0' && *recvMsg <= '9'))
{
getSig[i++] = *recvMsg;
recvMsg++;
}
i = 0;
tempSig.snrSignal = atoi(getSig);
memset(getSig, '\0', sizeof(getSig));
sig.AddTail(tempSig);
recvMsg--;
}
return bRet;
}
/*(3)手动模拟一些信号进行测试*/
CList<mSignal> allSignal;
//char signals[200] = {"* SV: 1 ELEV: 0 AZI: 0 SNR: 41"};
char signals[200] = {"* SV: 5 ELEV: 0 AZI: 0 SNR: 33\n* SV: 7 ELEV: 0 AZI: 0 SNR: 55\n* SV: 16 ELEV: 0 AZI: 0 SNR: 65"};
CString str;
GetAllSignal(allSignal, signals);
for (POSITION posi = allSignal.GetHeadPosition(); posi != NULL; allSignal.GetNext(posi))
{
str.AppendFormat(_T("SV:%d SNR:%d\n"), allSignal.GetAt(posi).svSignal, allSignal.GetAt(posi).snrSignal);
}
AfxMessageBox(str);