【问题标题】:Why is array of characters(char type) working with unicode characters (c++)?为什么字符数组(char 类型)与 unicode 字符(c++)一起使用?
【发布时间】:2021-12-25 10:28:30
【问题描述】:

当我写这段代码时:

using namespace std;

int main(){
    char x[] = "γεια σας";
    cout << x;
    return 0;
}

我注意到编译器给了我输出,我排除了γεια σας 虽然数组的类型是char,也就是说,它应该只接受 ASCII 字符。

那么为什么编译器没有报错呢?

【问题讨论】:

  • C++ 标准中没有任何内容表明char 适用于 ASCII 字符,您从哪里得到这个想法?
  • @UnholySheep 它也得到 EBCDIC 但我知道它没有得到 Unicode 字符
  • @Retired Ninja 是的,我听说过 utf-8,但我知道 utf-8 字符太大,所以 char 类型无法容纳它,因为它的范围是 0-255
  • 你知道错了。一个 utf-8 代码点被定义为适合 8 位,sizeof(char) 被定义为足够大以能够容纳它
  • @UnholySheep sizeof(char) 被定义为标准中的一个。 char 中的位数指定为至少 8 位,并且不需要 ASCII(因此没有什么可以阻止 char 被 utf-8 编码)。

标签: c++ unicode


【解决方案1】:

虽然数组的类型是char,也就是应该只接受ASCII字符。

你猜错了。

Unicode 有多种转换格式。一种流行的此类格式是 UTF-8。正如名称所暗示的那样,UTF-8 的代码单元是 8 位宽。总是可以使用char 来表示UTF-8 的代码单元,因为char 保证至少8 位宽。

【讨论】:

    【解决方案2】:

    99.99% 的可能性是以 UTF-8 格式存储的 Unicode 代码点。每个代码点都转换为一到四个字符。

    将 ASCII 范围内的 Unicode 转换为从 0x00 到 0x7f 的一个 ASCII 字节。有 2048 个码点被翻译成两个字节,二进制模式 110x xxxx 10yy yyyy,65536 被翻译成三个码点 1110 xxxx 10yy yyyy 10zz zzzz,剩下的变成四个字符 1111 0xxx 10yy yyyy 10zz zzzz 10uu uuuu。

    大多数 C 和 C++ 字符串函数都可以在 UTF-8 中正常工作。一个例外是 strncpy 或 strncat,它可能会创建一个不完整的代码点。旧的面试问题“反转字符中的字符串”变得更加复杂,因为反转代码点内的字节会产生废话。

    【讨论】:

      【解决方案3】:

      这里有一些代码展示了 C++ 的真正作用:

      #include <iostream>
      #include <iomanip>
      
      using namespace std;
      
      int main(){
          char x[] = "γεια σας";
          cout << x << endl;
          
          auto len = strlen(x);
          cout << "Length (in bytes): " << len << endl;
          for (int i = 0; i < len; i++)
              cout << "0x" << setw(2) << hex << static_cast<int>(static_cast<unsigned char>(x[i])) << ' ';
          cout << endl;
          return 0;
      }
      

      输出是:

      γεια σας
      Length (in bytes): 15
      0xce 0xb3 0xce 0xb5 0xce 0xb9 0xce 0xb1 0x20 0xcf 0x83 0xce 0xb1 0xcf 0x82 
      

      所以字符串占用 15 个字节,编码为UTF-8。 UTF-8 是一种 Unicode 编码,每个字符使用 1 到 4 个字节(在您可以使用文本光标选择的最小单位的意义上)。 UTF-8 可以保存在 char 数组中。尽管它被称为char,但它基本上对应的是一个字节,而不是我们通常认为的字符。

      【讨论】:

        猜你喜欢
        • 2021-12-07
        • 2011-10-02
        • 1970-01-01
        • 2010-11-23
        • 2018-10-30
        • 2022-06-10
        • 1970-01-01
        • 2017-07-08
        • 2022-01-10
        相关资源
        最近更新 更多