如何在Debian系统中正确显示带重音字符的std::wstring
关于std::wcout在法语Debian环境下显示带重音字符的问题
我在一台法语Debian机器上开发项目,项目大量使用std::wstring,其中部分字符串包含重音字符。我发现std::wcout有时无法正确显示带重音的std::wstring,以下是相关测试示例:
示例1:同时输出std::string和std::wstring
#include <iostream> int main() { const std::string accentuated_string = "str {grandma: mémère}" ; std::cout << accentuated_string << std::endl; // 输出 "str {grandma: mémère}" const std::wstring accentuated_wstring = L"wstr {grandma: mémère}" ; std::wcout << accentuated_wstring << std::endl; // 输出 "wstr {grandma: m�m�re}" }
示例2:仅输出std::wstring
移除初始的std::string后,�会被替换为?:
#include <iostream> int main() { const std::wstring accentuated_wstring = L"wstr {grandma: mémère}" ; std::wcout << accentuated_wstring << std::endl; // 输出 "wstr {grandma: m?m?re}" }
示例3:调用setlocale且仅输出std::wstring
添加setlocale调用且不显示std::string时,std::wstring能正常显示:
#include <iostream> int main() { constexpr auto encoding = "fr_FR.UTF-8"; for (const auto lc_type : {LC_ALL, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT, LC_IDENTIFICATION}) { setlocale( LC_ALL, encoding ); } //const std::string accentuated_string = "str {grandma: mémère}" ; //std::cout << accentuated_string << std::endl; // 始终输出 "grandma: mémère" const std::wstring accentuated_wstring = L"wstr {grandma: mémère}" ; std::wcout << accentuated_wstring << std::endl; // 输出 "grandma: mémère" !!! }
示例4:调用setlocale但先输出std::string
取消注释std::string的代码后,std::wstring显示异常的问题依然存在:
#include <iostream> int main() { constexpr auto encoding = "fr_FR.UTF-8"; for (const auto lc_type : {LC_ALL, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT, LC_IDENTIFICATION}) { setlocale( LC_ALL, encoding ); } const std::string accentuated_string = "str {grandma: mémère}" ; std::cout << accentuated_string << std::endl; // 始终输出 "grandma: mémère" const std::wstring accentuated_wstring = L"wstr {grandma: mémère}" ; std::wcout << accentuated_wstring << std::endl; // 输出 wstr {grandma: m�m�re} }
我知道在Linux环境下通常建议避免使用std::wstring,但仍想搞清楚以下几个现象的原因:
- 为什么
wcout会打印出这些奇怪的字符? - 为什么调用
setlocale可能会解决问题? - 为什么先显示
std::string会导致后续的std::wstring显示出错?
系统环境信息
(base) ➜ ~ locale LANG=fr_FR.UTF-8 LANGUAGE= LC_CTYPE="fr_FR.UTF-8" LC_NUMERIC="fr_FR.UTF-8" LC_TIME="fr_FR.UTF-8" LC_COLLATE="fr_FR.UTF-8" LC_MONETARY="fr_FR.UTF-8" LC_MESSAGES="fr_FR.UTF-8" LC_PAPER="fr_FR.UTF-8" LC_NAME="fr_FR.UTF-8" LC_ADDRESS="fr_FR.UTF-8" LC_TELEPHONE="fr_FR.UTF-8" LC_MEASUREMENT="fr_FR.UTF-8" LC_IDENTIFICATION="fr_FR.UTF-8" LC_ALL= (base) ➜ ~ echo $LANG fr_FR.UTF-8 (base) ➜ ~ g++ --version g++ (Debian 10.2.1-6) 10.2.1 20210110 (base) ➜ ~ file -bi main.cpp text/x-c; charset=utf-8
内容的提问来源于stack exchange,提问作者GabrielGodefroy
相关产品推荐
相关产品推荐

