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

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;
}

注意事项

  1. 确保XML文件的编码为UTF-8,如果是其他编码(如GBK),需修改转换时的代码页参数(例如GBK对应CP_ACP)。
  2. 若需兼容C++17及以后版本,建议使用第三方编码库(如ICU)替代std::wstring_convert。

内容的提问来源于stack exchange,提问作者Andreas Schulz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 06:33:10