C++中如何查找MFC CMap内含空格键的对应值
MFC CMap 含空格键查找失败的正确解决方法
问题根源
查找失败和键是否包含空格没有直接关联,核心是CMap声明和使用逻辑存在两个本质错误:
- CMap键比对逻辑不符合预期。你声明的
CMap<LPCTSTR,CString> testMap;将键类型设置为LPCTSTR(即字符串指针类型),CMap对于指针类型的键,默认直接比对指针的内存地址,不会比对指针指向的字符串内容。不带空格的键偶尔查找成功,只是因为插入和查找时传入的短字符串/常量字符串刚好指向同一块内存地址,属于概率性巧合,不是功能正常。 - Lookup传参存在野指针风险。你直接在Lookup参数列表中调用
key.MakeLower()并强转为LPCTSTR传入,MakeLower返回的是CString对象引用,如果传入的是临时CString对象,表达式执行完临时对象立刻销毁,传入的指针就会变成野指针,自然无法匹配到正确结果。
正确实现方式
- 修正CMap模板声明,使用
CString作为键类型,让CMap自动调用CString的内容比较逻辑做哈希和匹配,从根源避免指针地址比对的问题。CMap的四个模板参数固定顺序为CMap<键类型, 键传参类型, 值类型, 值传参类型>,不要填错顺序。 - 提前处理待查找键的格式(比如转全小写),不要在Lookup的参数列表中临时做字符串修改,避免临时对象销毁导致的野指针。
修正后的可运行代码
// 正确声明CMap结构:键为CString,传参用LPCTSTR;值为CString,传参用CString CMap<CString, LPCTSTR, CString, CString> testMap; // 插入测试数据:键为全小写的"hello world",值为"Test" testMap[_T("hello world")] = _T("Test"); // 查找逻辑 CString findKey = _T("HELLO WORLD"); CString outVal; findKey.MakeLower(); // 提前将待查找键转为和插入时一致的全小写格式 if (testMap.Lookup(findKey, outVal)) { // 此处可正常获取到值"Test",无论键是否包含空格都能匹配 // 业务逻辑写在这里 }
特殊场景如果必须用LPCTSTR作为键类型,需要自行实现CMap专属的哈希计算函数和键比较函数,手动实现字符串内容比对逻辑,否则永远会出现内容相同但地址不同的键匹配失败的问题,这种方案维护成本较高,非必要不推荐使用。
内容的提问来源于stack exchange,提问作者S J
相关产品推荐
相关产品推荐

