我打算创建一个处理字符串的库,但我想到的第一件事就是支持所有语言,在这些语言中,亚洲语言如中文、日语以及从右到左的语言如阿拉伯语、波斯语等等。
那么,我想知道以数据类型char*
和std::string
表示的"UTF-8“是否足以支持所有的读写语言,或者我应该使用以数据类型wchar_t*
和std::wstring
表示的"UTF-16”吗?
简而言之,应该使用哪种数据类型并适合此任务,无论是这些数据类型还是其他数据类型?
发布于 2020-03-12 01:00:11
你的问题中有一些混淆,所以我将从你可能正在寻找的答案开始,然后从那里开始:
您应该使用UTF-8编码,除非您有很好的理由不使用UTF-8编码。有几个很好的原因,但没有一个与支持什么语言有关。
UTF-8和UTF-16只是编码Unicode的不同方式。您还可以使用UTF-32对Unicode进行编码。您甚至可以用GB18030或其他几种编码之一对Unicode进行编码。只要编码可以处理所有Unicode代码点,那么它将涵盖相同数量的语言、字形、脚本、字符等(准确地确定Unicode代码点的含义本身是一个微妙的主题,我不想在这里讨论,但出于这些目的,我们将其视为“字符”。)
您通常应该使用UTF-8,因为如果您使用基于拉丁语的脚本,那么它将非常有效,而且它是该生态系统中最受支持的编码。也就是说,对于某些问题,UTF-16或UTF-32可能更有效。但是如果没有特定的原因,您应该使用UTF-8。
数据类型char*
和std::string
不代表UTF-8。它们代表一系列char
。这就是他们所代表的一切。这段char
序列可以用多种方式解释。将其解释为UTF-8是相当常见的,但我甚至不认为这是最常见的解释(许多系统将其视为扩展ASCII,这就是为什么非英语文本在系统之间移动时经常出现乱码)。
如果您想使用UTF8,那么除了使用std:string
之外,您还需要做更多的事情。您需要一个UTF-8处理库,最常见的是用于简单使用的std::locale
或用于复杂问题的ICU。UTF-8字符的长度可以在1到4 char
之间,因此在应用字符处理时必须非常周到。最常见的错误是UTF-8不支持随机访问。您不能只跳到字符串中的第32个字母。你必须从头开始处理它才能找到所有的字符分隔符。如果从任意点开始处理UTF-8字符串,可能会跳到字符的中间。
通过组合字符,UTF-8编码(在许多系统中)可以变得任意长。视觉上的单个“字符”被编码为UTF-8格式的25个UTF值的序列。(当然,它在wchar_t
-16中编码为12个UTF值。没有Unicode编码,您就不必考虑组合字符。)
另一方面,UTF-8非常强大,因为对于某些问题,您通常可以忽略它。字符A
完全按照ASCII码( 65 )进行编码,并且UTF-8承诺序列中不会有65且不是A
的字节。因此,搜索特定的ASCII序列不需要特殊的处理(就像在UTF-16中那样)。
作为NathanOliver points out,使用任何Unicode编码都只支持Unicode支持的语言、字形、脚本、字符等。作为一个实际问题,这是世界上绝大多数常用的语言。它不是每种语言(它在处理某些它所支持的语言方面也有缺陷),但它是目前为止我们拥有的最全面的系统。
发布于 2020-03-12 00:09:25
不,UTF-8还不足以支持所有语言。来自As Yet Unsupported Scripts
当前不受支持。
https://stackoverflow.com/questions/60640010
复制相似问题