C++宽字符(wchar_t)非通用Unicode类型,Windows用UTF-16(16位),Linux/macOS用UTF-32(32位),跨平台不可移植;应优先选用UTF-8编码的std::string或第三方库处理Unicode。

在C++中处理宽字符(wchar_t)和std::wstring,核心是理解其设计目的、平台差异与实际使用限制。它主要用于支持Unicode(但不是UTF-8),尤其在Windows API或需要处理本地化宽字符串的场景中;但在跨平台项目中,更推荐用char8_t + UTF-8 或第三方库(如utf8cpp、icu)。
宽字符不是“通用Unicode类型”
wchar_t的大小和编码含义由编译器与平台决定:
- Windows(MSVC/MinGW):通常为16位,编码是UTF-16(可变长,含代理对)
- Linux/macOS(GCC/Clang):通常为32位,编码是UTF-32(固定长度,一个
wchar_t对应一个Unicode码点)
这意味着sizeof(wchar_t)不可移植,std::wstring也不能跨平台直接序列化或网络传输。别假设L"€".length() == 1——在Windows上它可能是2(代理对),在Linux上是1。
输入输出需匹配locale和流类型
用std::wcout、std::wcin前必须设置正确的全局locale,否则可能输出乱码或静默失败:
立即学习“C++免费学习笔记(深入)”;
- Windows下常用:
std::locale::global(std::locale("")); // 使用系统区域设置 - Linux/macOS下建议显式指定:
std::locale::global(std::locale("en_US.UTF-8")) - 确保控制台/终端本身支持宽字符显示(例如Windows Terminal、iTerm2),否则
wcout 可能只打印空格
与C风格字符串和API交互要小心转换
Windows API大量使用LPCWSTR(即const wchar_t*),而POSIX函数基本不接受wchar_t*。转换时避免手写循环:
- 用
std::wstring::c_str()获取只读const wchar_t*,传给Windows函数(如CreateFileW) - 从多字节转宽字符:Windows用
MultiByteToWideChar(CP_UTF8, ...);Linux用mbstowcs()(注意目标缓冲区大小) - 反向转换(宽→多字节):Windows用
WideCharToMultiByte(CP_UTF8, ...);Linux用wcstombs()
切勿用reinterpret_cast在char*和wchar_t*间强制转换——编码不同,字节布局不兼容。
替代方案更实用
除非必须对接Windows GUI或COM接口,否则优先考虑:
- 内部统一用UTF-8编码的
std::string(C++20起可用std::u8string) - 用
std::text_encoding(C++26草案)或成熟库(如utf8cpp)做编码验证与转换 - 读写文件时明确指定编码(如用
std::ofstream配合std::codecvt_utf8_utf16已弃用,改用std::from_chars/std::to_chars或第三方)
宽字符体系在C++标准中功能有限、平台行为分裂,现代项目中它更多是“遗留互操作层”,而非首选文本抽象。










