gpt4 book ai didi

c++ - 在C++中将十进制转换为Unicode Char

转载 作者:太空狗 更新时间:2023-10-29 23:51:10 28 4
gpt4 key购买 nike

输出时,如何将十进制数字(例如225)转换为其对应的Unicode字符?我可以将ASCII字符从十进制转换为如下字符:

int a = 97;
char b = a;
cout << b << endl;

它输出字母“a”,但是当我使用数字225或任何非ascii字符时,它只会输出一个问号。

最佳答案

首先,不是您的C++程序将写入标准输出的字节字符串转换为可见字符。它是您的终端机(或更常见的是,现在是您的终端机模拟器)。不幸的是,无法询问终端如何期望对字符进行编码,因此需要在您的环境中进行配置。通常,这是通过设置适当的locale环境变量来完成的。

像大多数与终端有关的事情一样,如果语言环境配置系统的开发没有悠久的传统软件和硬件的历史,那么它们可能会大为不同。如重音字母,音节或表意文字。这就是生活。

Unicode非常酷,但是必须面对写作系统的特定计算机历史来部署Unicode,这意味着面对软件工程中各种固执却根本矛盾的观点时要做出很多妥协。社区,dicho sea de paso是一个社区,在这个社区中,撞头是比较普遍的折衷方案。 Unicode最终成为或多或少成为标准的事实证明了其扎实的技术基础以及其发起人和设计人员(尤其是马克·戴维斯)的毅力和政治技巧,尽管我基本上接受了这一事实,但我还是这样说。到现在已经有二十多年了。

谈判和妥协历史的一方面是,有多种方法可以将Unicode字符串编码为比特。至少有三种方式,其中两种取决于字节序有两种不同的版本;此外,这些编码系统中的每一个都有专用的风扇(因此也有教条式的批评者)。特别是Windows早先决定采用16位编码UTF-16,而大多数unix(-like)系统使用可变长度8到32位编码UTF-8。 (从技术上讲,UTF-16也是16或32位编码,但这超出了此限制的范围。)

在Unicode之前,每个国家/地区/语言都使用自己的特有的8位编码(或者至少是那些使用少于194个字符的字母书写语言的国家/地区)。因此,将编码配置为本地表示形式的一般配置的一部分是有意义的,例如月份名称,货币符号以及什么字符将数字的整数部分与其小数部分分开。既然Unicode有了广泛的(但仍远未达到普遍的)融合,考虑到所有语言都可以表示相同的Unicode字符串,并且编码通常更特定于该特定语言,那么语言环境包含Unicode编码的特定样式似乎很奇怪。所使用的软件要比国家特殊性高。就是这样,这就是为什么在我的Ubuntu机器上,环境变量LANG设置为es_ES.UTF-8而不是es_ES的原因。 (或者应该是es_PE,除了我在该语言环境中遇到了一些小问题。)如果您使用的是Linux系统,则可能会发现类似的内容。

从理论上讲,这意味着我的终端仿真器(konsole,它发生了,但是种类很多)期望看到UTF-8序列。而且,的确,konsole足够聪明,可以检查语言环境设置并设置其默认编码以进行匹配,但是我可以随意更改编码(或语言环境设置),并且可能会造成困惑。

因此,假设您的语言环境设置和终端使用的编码实际上是同步的,它们应该在配置良好的工作站上,然后返回C++程序。现在,C++程序需要弄清楚应该使用哪种编码,然后将其使用的任何内部表示形式转换为外部编码。

幸运的是,如果您通过以下方式进行合作,则C++标准库应能够正确处理此问题:

  • 告诉标准库使用配置的语言环境,而不是默认的C(即,根据英语,仅不带重音的字符)语言环境;和
  • 使用基于wchar_t(或其他宽字符格式)的字符串和iostream。

  • 如果这样做,从理论上讲,您既不需要知道 wchar_t对标准库意味着什么,也不需要知道特定的位模式对终端仿真器意味着什么。因此,我们尝试:
    #include <iostream>
    #include <locale>

    int main(int argc, char** argv) {
    // std::locale() is the "global" locale
    // std::locale("") is the locale configured through the locale system
    // At startup, the global locale is set to std::locale("C"), so we need
    // to change that if we want locale-aware functions to use the configured
    // locale.
    // This sets the global" locale to the default locale.
    std::locale::global(std::locale(""));

    // The various standard io streams were initialized before main started,
    // so they are all configured with the default global locale, std::locale("C").
    // If we want them to behave in a locale-aware manner, including using the
    // hopefully correct encoding for output, we need to "imbue" each iostream
    // with the default locale.
    // We don't have to do all of these in this simple example,
    // but it's probably a good idea.
    std::cin.imbue(std::locale());
    std::cout.imbue(std::locale());
    std::cerr.imbue(std::locale());
    std::wcin.imbue(std::locale());
    std::wcout.imbue(std::locale());
    std::wcerr.imbue(std::locale());

    // You can't write a wchar_t to cout, because cout only accepts char. wcout, on the
    // other hand, accepts both wchar_t and char; it will "widen" char. So it's
    // convenient to use wcout:
    std::wcout << "a acute: " << wchar_t(225) << std::endl;
    std::wcout << "pi: " << wchar_t(960) << std::endl;
    return 0;
    }

    这适用于我的系统。 YMMV。祝好运。

    小注:我已经遇到很多人,他们认为 wcout自动写“宽字符”,因此使用它会产生UTF-16或UTF-32之类的东西。没有。它产生与 cout完全相同的编码。区别不在于它输出什么,而在于它接受什么作为输入。实际上,它实际上与 cout并没有什么不同,因为它们都连接到同一OS流,该OS流一次只能具有一种编码。

    您可能会问为什么有必要使用两个不同的 iostreamcout为什么不能只接受 wchar_tstd::wstring值?我实际上没有答案,但是我怀疑这是不为不需要的功能付费的哲学的一部分。或类似的东西。如果您知道了,请告诉我。

    关于c++ - 在C++中将十进制转换为Unicode Char,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23461499/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com