gpt4 book ai didi

c++ - 使用 C++17 处理 Unicode 的高效、符合标准的机制是什么?

转载 作者:可可西里 更新时间:2023-11-01 16:06:12 26 4
gpt4 key购买 nike

短版:
如果我想编写可以有效执行 Unicode 字符操作的程序,能够输入和输出 UTF-8 或 UTF-16 编码的文件。使用 C++ 执行此操作的合适方法是什么?
长版:
C++ 早于 Unicode,并且两者都已经有了显着的发展。我需要知道如何编写符合标准且无泄漏的 C++ 代码。我需要一个明确的答案:

  • 我应该选择哪个字符串容器?
  • std::string用UTF-8?
  • std::wstring (不太了解)
  • std::u16string使用 UTF-16?
  • std::u32string使用 UTF-32?

  • 我应该完全坚持使用上述容器之一还是在需要时更换它们?
  • 使用 UTF 字符串时,我可以在字符串文字中使用非英语字符吗,例如波兰语字符:ąćęłńśźż等等?
  • 当我们在 std::string 中存储 UTF-8 编码的字符时会发生什么变化?它们仅限于一字节的 ASCII 字符还是可以是多字节的?
    当我执行以下操作时会发生什么?
     std::string s = u8"foo";
    s += 'x';
  • wchar_t 和其他多字节字符类型有什么区别?是 wchar_t字符或 wchar_t能够存储UTF编码的字符串文字?
  • 最佳答案

    Which string container should I pick?


    这真的由您决定,根据您自己的特定需求。您提供的任何选择都可以使用,而且它们各有优缺点。一般来说,UTF-8 适合用于存储和通信目的,并且向后兼容 ASCII。而处理 Unicode 数据时,UTF-16/32 更易于使用。

    std::wstring (don't really know much about it)

    wchar_t尺寸依赖于编译器,甚至依赖于平台。例如,在 Windows 上, wchar_t是 2 个字节,使得 std::wstring可用于 UTF-16 编码的字符串。在其他平台上, wchar_t可能是 4 个字节,使得 std::wstring可用于 UTF-32 编码的字符串。这就是为什么 wchar_t/ std::wstring一般不用于可移植代码,为什么 char16_t/ std::u16stringchar32_t/ std::u32string是在 C++11 中引入的。偶 char UTF-8 可能存在可移植性问题,因为 char可以根据编译器供应商的要求进行签名或不签名,这就是为什么 char8_t/ std::u8string是在 C++20 中为 UTF-8 引入的。

    Should I stick entirely to one of the above containers or change them when needed?


    使用任何适合您需要的容器。
    通常,您应该在整个代码中使用一种字符串类型。仅在字符串数据进入/离开程序的边界处执行数据转换。例如,读/写文件、网络通信、平台系统调用等。

    How to properly convert between them?


    有很多方法可以处理。
    C++11 及更高版本有 std::wstring_convert/ std::wbuffer_convert .但是这些在 C++17 中被弃用了。
    有第三方Unicode转换库,如ICONV、ICU等。
    有C库函数,平台系统调用等。

    Can I use non-english characters in string literals, when using UTF strings, such as Polish characters: ąćęłńśźż etc?


    是的,如果您使用适当的字符串文字前缀: u8对于 UTF-8。 L对于 UTF-16 或 UTF-32(取决于编译器/平台)。 u16对于 UTF-16。 u32对于 UTF-32。
    另外,请注意用于保存源文件的字符集会影响编译器解释字符串文字的方式。因此,请确保您选择保存文件的任何字符集(例如 UTF-8)告诉编译器该字符集是什么,否则您可能会在运行时得到错误的字符串值。

    What changes when we store UTF-8 encoded characters in std::string? Are they limited to one-byte ASCII characters or can they be multi-byte?


    每个字符串字符可以是单字节,也可以是 Unicode 代码点的多字节表示的一部分。这取决于字符串的编码和被编码的字符。
    正如 std::wstring (当 wchar_t 为 2 个字节时)和 std::u16string可以保存包含 Unicode BMP 之外的补充字符的字符串,这需要 UTF-16 代理进行编码。
    当字符串容器包含 UTF 编码的字符串时,每个“字符”只是一个 UTF 编码的代码单元。 UTF-8 将 Unicode 代码点编码为 1-4 个代码单元(1-4 char s in a std::string) 。UTF-16 将代码点编码为 1-2 个代码单元(1-2 wchar_t s/ char16_tstd::wstring/ std::u16string 中。UTF-32 将代码点编码为 1 个代码单元(在 char32_t 中为 1 std::u32string)。

    What happens when i do the following?

    std::string s = u8"foo";
    s += 'x';

    正是您所期望的。一个 std::string持有 char元素。不管编码如何, operator+=(char)将简单地附加一个 char到最后 std::string .

    How can I distinguish UTF char[] and non-UTF char[] or std::string?


    您需要了解字符串原始编码的外部知识,或者对 char[] 执行您自己的启发式分析。/ std::string数据以查看它是否符合 UTF。

    What are differences between wchar_t and other multi-byte character types?


    字节大小和 UTF 编码。 char = ANSI/MBCS 或 UTF-8 wchar_t = DBCS、UTF-16 或 UTF-32,取决于编译器/平台 char8_t = UTF-8 char16_t = UTF-16 char32_t = UTF-32

    Is wchar_t character or wchar_t string literal capable of storing UTF encodings?


    是的,UTF-16 或 UTF-32,取决于编译器/平台。对于 UTF-16,单个 wchar_t只能保存 BMP 中的代码点值。单 wchar_t在 UTF-32 中可以保存任何代码点值。一个 wchar_t string 可以以任一编码方式对所有代码点进行编码。

    How to properly manipulate UTF strings (such as toupper/tolower conversion) and be compatible with locales simultaneously?


    这是一个非常广泛的话题,值得单独提出一个问题。

    关于c++ - 使用 C++17 处理 Unicode 的高效、符合标准的机制是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48816848/

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