直接在swscanf中使用CString搭配STL set时的异常行为问询
问题原因
核心错误是swscanf调用时的参数类型不匹配,触发了未定义行为,具体如下:
swscanf的%ls(宽字符版本%s)格式符要求接收参数为已分配空间的wchar_t*缓冲区指针,你直接传入CString类对象本身,会导致swscanf直接改写CString对象的内存布局,而不是写入字符串存储区。这会破坏CString内部的长度、引用计数、缓冲区指针等元数据,所有循环内创建的CString对象内容都会异常,插入set时被判定为相同值,最终集合只有1个元素。- 附加错误:文件路径
L"F:\test.txt"中的反斜杠未转义,\t会被编译器解析为制表符,大概率会导致文件打开失败,后续操作都是非法内存访问。
修复方案
修改读取逻辑,先读取到栈上的wchar_t缓冲区再赋值给CString即可:
#include "stdafx.h" #include <iostream> #include <set> #include <atlstr.h> #include <cstdio> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { wchar_t line[1024] = {0}; // 转义路径反斜杠 FILE * pFile = _wfopen(L"F:\\test.txt", L"rt"); if (!pFile) { wcout << L"文件打开失败" << endl; return -1; } set<CString> cstr_set; wchar_t buf[1024] = {0}; while (fgetws(line, 1024, pFile)) { CString cstr; // 先读到wchar_t缓冲区,再赋值给CString if (swscanf(line, L"%ls", buf) == 1) { cstr = buf; cstr_set.insert(cstr); } } fclose(pFile); // 宽字符串用wcout输出 wcout << L"count: " << cstr_set.size() << endl; return 0; }
内容的提问来源于stack exchange,提问作者secuman
相关产品推荐
相关产品推荐

