如何显示带有强调字符的 std::wstring

How to display std::wstring with accentuated characters

提问人:GabrielGodefroy 提问时间:7/5/2023 更新时间:7/5/2023 访问量:47

问:

我正在做一个项目(在法国的 debian 机器上运行),其中被大量使用。其中一些字符串是加重的。std::wstring

我有点困惑,有时无法正确显示.std::wcoutstd::string

以下是一些示例:

#include <iostream>

int main() {

    const std::string accentuated_string = "str {grandma: mémère}" ;
    std::cout << accentuated_string << std::endl; // prints "str {grandma: mémère}""

    const std::wstring accentuated_wstring = L"wstr {grandma: mémère}" ;
    std::wcout << accentuated_wstring << std::endl; // prints "wstr {grandma: m�m�re}"
}

如果去掉首字母,则替换为std::string?

#include <iostream>
int main() {
    const std::wstring accentuated_wstring = L"wstr {grandma: mémère}" ;
    std::wcout << accentuated_wstring << std::endl; // prints "wstr {grandma: m?m?re}"
}

现在,如果我添加一些并且仍然隐藏 std::string,我得到setlocale

#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; // always print "grandma: mémère"

    const std::wstring accentuated_wstring = L"wstr {grandma: mémère}" ;
    std::wcout << accentuated_wstring << std::endl; // prints "grandma: mémère" !!!
}

但是当取消注释 时,它仍然失败:std::string

#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; // always print "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 可能会有所帮助?
  • 为什么在后显示 A 时,先显示 A 会导致错误?std::stringstd::wstring

注意:我的系统是用法语 UTF-8 参数化的:

(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
C++ UTF-8 字符编码 wstring

评论

2赞 john 7/5/2023
wcout两者最终都使用 .C 流可以是窄方向的,也可以是宽方向的。最初不处于两个方向,但第一个 I/O 操作将使其处于窄方向或宽方向。我相信这就是为什么最初的使用会改变印刷品的后续使用。更多信息在这里,请注意,一旦决定就不可能切换方向,因此您可能必须选择或 。coutstdoutstdoutcoutwcoutcoutwcout

答: 暂无答案