使用CT2CA转换CString为UTF-8时字符损坏,如何正确写入XML?
问题:UTF-8编码XML写入时特殊字符损坏
尝试将含特殊字符的文本(如Estudante - Leitura da Bíblia)写入UTF-8编码XML文件,使用tinyxml2库时出现葡萄牙语、波兰语等特殊字符损坏的情况。已确认CString原内容正确,但tinyxml2的SetText要求传入UTF-8编码字符串,当前转换逻辑存在问题。
核心问题
- 字符转换错误:
CT2CA(strValue)默认采用系统ANSI编码(如Windows-1252)转换,而非UTF-8,导致特殊字符转码后失效。 - 文件打开模式错误:以文本模式(
"w")打开文件时,系统会自动转换换行符并根据本地编码处理字节流,破坏tinyxml2输出的UTF-8原生字节。
修复方案
1. 修正CString到UTF-8的转换
显式指定转换编码为CP_UTF8,确保传入SetText的是标准UTF-8格式的char*:
auto AddLabel = [](tinyxml2::XMLDocument& rDoc, tinyxml2::XMLElement* pLabels, LPCSTR szElement, CString strValue, int iIndex = -1) { tinyxml2::XMLElement* pLabel = rDoc.NewElement(szElement); if (pLabels != nullptr && pLabel != nullptr) { // 显式指定UTF-8编码转换 pLabel->SetText(CT2CA(strValue, CP_UTF8)); if (iIndex != -1) { pLabel->SetAttribute("Index", iIndex); } pLabels->InsertEndChild(pLabel); } };
2. 以二进制模式打开文件
tinyxml2的SaveFile输出原生UTF-8字节流,需用二进制模式("wb")打开文件,避免文本模式的自动转码:
// 修改SaveToXML中的文件打开逻辑 const auto eResult = _tfopen_s(&fStream, strFileXML, _T("wb"));
3. 显式添加UTF-8编码声明(推荐)
在XML文档开头添加编码声明,确保编辑器能正确识别文件编码:
// 创建XMLDocument后插入声明 tinyxml2::XMLDeclaration* decl = rDocXML.NewDeclaration("xml version=\"1.0\" encoding=\"UTF-8\""); rDocXML.InsertFirstChild(decl);
验证
写入完成后,用Notepad++打开XML文件,通过「编码」菜单确认文件为UTF-8编码,特殊字符应正常显示。调用CA2CT(pLabel->GetText(), CP_UTF8)可正确还原原CString内容。
内容的提问来源于stack exchange,提问作者Andrew Truckle
相关产品推荐
相关产品推荐

