You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

直接在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 18:27:02