Pugixml禁用宽字符模式下std::wstring赋值失败求助
禁用PUGIXML_WCHAR_MODE后,如何将Pugixml解析的字符串转为wstring赋值给Country::Name
问题背景
使用Pugixml解析XML文件,已在配置中禁用PUGIXML_WCHAR_MODE,但业务类Country的Name字段为std::wstring类型。尝试直接将Pugixml返回的std::string转为wstring(包括直接构造、调用get()方法)均无效,无法正确赋值。
类定义:
class Country { public: int ID; std::wstring Name; };
当前解析代码:
std::vector<Country> readCountriesFromXML(const std::string& filename) { xml_document doc; doc.load_file(filename.c_str()); for (xml_node countryNode : doc.child("Daten").children("Country")) { Country country; country.ID = countryNode.child("ID").text().as_int(); country.Name = countryNode.child("Name").text().as_string(); std::wstring wName(country.Name.begin(), country.Name.end()); country.Name = wName; countries.push_back(country); } return countries; }
问题根源
禁用PUGIXML_WCHAR_MODE后,Pugixml默认以窄字符(char)处理所有字符串,as_string()返回的是const char*。直接通过迭代器构造wstring只是逐字节转换,无法处理多字节编码(如UTF-8的非ASCII字符),会导致乱码或赋值失败。
解决方案
需要做编码转换,将Pugixml返回的窄字符串(通常是UTF-8编码)转为宽字符串wstring。以下是两种可行方案:
方案1:跨平台标准库实现(C11至C14可用)
利用<codecvt>头文件的工具类完成UTF-8到宽字符的转换:
#include <locale> #include <codecvt> std::wstring utf8_to_wstring(const std::string& str) { std::wstring_convert<std::codecvt_utf8<wchar_t>> converter; return converter.from_bytes(str); }
修改后的解析代码:
std::vector<Country> readCountriesFromXML(const std::string& filename) { std::vector<Country> countries; // 补充缺失的变量声明 pugi::xml_document doc; // 增加加载错误检查 pugi::xml_parse_result result = doc.load_file(filename.c_str()); if (!result) { return countries; } for (pugi::xml_node countryNode : doc.child("Daten").children("Country")) { Country country; country.ID = countryNode.child("ID").text().as_int(); // 使用编码转换函数赋值 std::string name_str = countryNode.child("Name").text().as_string(); country.Name = utf8_to_wstring(name_str); countries.push_back(country); } return countries; }
方案2:Windows平台专用API
如果仅需兼容Windows,可使用系统APIMultiByteToWideChar,避免标准库弃用问题(std::wstring_convert在C++17中被标记为弃用):
#include <windows.h> std::wstring utf8_to_wstring(const std::string& str) { if (str.empty()) return L""; // 计算所需宽字符长度 int size_needed = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), NULL, 0); std::wstring wstr(size_needed, 0); // 执行转换 MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), &wstr[0], size_needed); return wstr; }
注意事项
- 确保XML文件的编码为UTF-8,如果是其他编码(如GBK),需修改转换时的代码页参数(例如GBK对应
CP_ACP)。 - 若需兼容C++17及以后版本,建议使用第三方编码库(如ICU)替代
std::wstring_convert。
内容的提问来源于stack exchange,提问作者Andreas Schulz
相关产品推荐
相关产品推荐

