字符集在字符串和 wstring 中的存储方式
how character sets are stored in strings and wstrings?
所以,我一直在尝试对字符串和wstring进行一些研究,因为我需要了解它们如何为我正在创建的程序工作,所以我也研究了ASCII和Unicode,以及UTF-8和UTF-16。
我相信我对这些工作原理的概念有一个很好的理解,但我仍然遇到麻烦的是它们实际上如何存储在"char"、"string"、"wchar_t"和"wstring"中。
所以我的问题如下:
- 字符集和编码用于字符和wchar_t? 这些类型是否仅限于使用这些字符集/编码?
- 如果它们不限于这些字符集/编码,如何确定特定字符集或wchar_t使用哪种字符集/编码? 例如,它是在编译时自动决定的,还是我们必须明确告诉它使用什么?
- 据我了解,UTF-8 在使用集合中的前 128 个码位时使用 1 个字节,但在使用码位 128 及以上时可以使用超过 1 个字节。如果是这样,如何存储?例如,如果它只使用 1 个字节,它是否只是简单地与 ASCII 相同地存储?类型(字符或wchar_t或其他(如何知道它使用了多少字节?
- 最后,如果我的理解是正确的,我明白为什么 UTF-8 和 UTF-16 不兼容,例如。 字符串不能在需要字符串的地方使用。但是在需要 wstring 的程序中,最好是编写一个从字符串到 wstring 的转换函数,并在需要 wstring 使我的代码完全基于字符串或只是在需要时使用 wstring 时使用它?
的任何问题措辞不正确或使用错误的术语,请告诉我,因为我正在尽我所能解决这个问题。
顺便说一句,我在C++工作
-
它们使用您想要的任何字符集和编码。这些类型并不意味着特定的字符集或编码。它们甚至不暗示字符 - 您可以愉快地与他们一起做数学问题。不过不要那样做,这很奇怪。
-
你如何输出文本?如果是控制台,控制台将决定与每个值关联的字符。如果是某个图形工具包,则由工具包决定。控制台和工具包往往符合标准,因此现在它们很有可能使用 unicode。在较旧的系统上,任何事情都可能发生。
-
对于范围 0-127,UTF8 与 ASCII 具有相同的值。除此之外,它变得有点复杂;这在这里解释得很好:https://en.wikipedia.org/wiki/UTF-8#Description
-
wstring 是由 wchar_t 组成的字符串,但遗憾的是wchar_t在不同的平台上实现方式不同。例如,在Visual Studio上它是16位(可用于存储UTF16(,但在GCC上它是32位(因此可用于直接存储Unicode代码点(。如果您希望代码可移植,则需要注意这一点。就个人而言,我选择只以 UTF8 格式存储字符串,并仅在需要时进行转换。
哪个字符集和编码用于字符和wchar_t?这些类型是否仅限于使用这些字符集/编码?
这不是由语言标准定义的。每个编译器都必须与操作系统就使用哪些字符代码达成一致。我们甚至不知道有多少位用于char
和wchar_t
.
在某些系统上char
是 UTF-8,在其他系统上它是 ASCII 或其他东西。在 IBM 大型机上,它可以是 EBCDIC,一种在定义 ASCII 之前已经在使用的字符编码。
如果它们不限于这些字符集/编码,如何确定特定字符集或wchar_t使用哪种字符集/编码? 例如,它是在编译时自动决定的,还是我们必须明确告诉它使用什么?
编译器知道什么适合每个系统。
据我了解,UTF-8 在使用集合中的前 128 个码位时使用 1 个字节,但在使用码位 128 及以上时可以使用超过 1 个字节。如果是这样,如何存储?例如,如果它只使用 1 个字节,它是否只是简单地与 ASCII 相同地存储?类型(字符或wchar_t或其他(如何知道它使用了多少字节?
UTF-8 的第一部分与相应的 ASCII 代码相同,并存储为单个字节。较高的代码将使用两个或多个字节。
char
类型本身只存储字节,不知道我们需要多少字节来形成一个字符。这是由其他人决定的。
wchar_t
也是如此,在Windows上是16位,但在其他系统(如Linux(上是32位。
最后,如果我的理解是正确的,我明白为什么 UTF-8 和 UTF-16 不兼容,例如。 字符串不能在需要字符串的地方使用。但是在需要 wstring 的程序中,最好是编写一个从字符串到 wstring 的转换函数,并在需要 wstring 使我的代码完全基于字符串或只是在需要时使用 wstring 时使用它?
您可能需要转换。不幸的是,由于字符大小和编码不同,不同系统所需的转换会有所不同。
在以后的C++标准中,您有新的char16_t
和char32_t
类型,字符串类型为u16string
和u32string
。这些具有已知的大小和编码。
关于所用编码的所有内容都是实现定义的。检查编译器文档。这取决于默认locale
、源文件的编码和操作系统控制台设置。
像 string
、wstring
、对它们的操作和 C 工具(如 strcmp
/wstrcmp
(等类型期望固定宽度的编码。因此,它不能与 UTF8 或 UTF16 等可变宽度的一起使用(但可以与例如 UCS-2 一起使用(。如果要存储可变宽度编码的字符串,则需要小心,不要对其使用固定宽度的操作。C-string确实有一些函数可以在标准库中操作此类字符串。您可以使用 codecvt 标头中的类在C++字符串的不同编码之间进行转换。
我会避免wstring
并使用C++11 确切宽度的字符串:std::u16string
或 std::u32string
作为一个例子,这里有一些关于Windows如何使用这些类型/编码的信息。
-
char
存储 ASCII 值(带有非 ASCII 值的代码页( -
wchar_t
存储 UTF-16,请注意,这意味着某些 unicode 字符将使用 2 个wchar_t
如果您调用系统函数,例如 puts
,头文件实际上会选择puts
或_putws
,具体取决于您的设置方式(即如果您使用的是 unicode(。
因此,在Windows上没有对UTF-8的直接支持,这意味着如果您使用char
来存储UTF-8编码的字符串,则必须将它们隐藏为UTF-16并调用相应的UTF-16系统函数。
- 在reactor中存储eventHandlers的最佳方式是什么
- 为什么我可以将变量存储在不是其最小对齐方式的倍数的地址?
- 合法的方式将destructor信息存储到void*
- 在c++中存储一个对象或不存储对象的首选方式是什么
- 数字的存储方式
- 如何以最佳方式将高分辨率图像数据存储在无符号字符*中C++
- 将图形存储到内存中的最佳方式
- 存储收藏的最佳实践方式
- 存储多维可变长度数据的最有效(但又足够灵活)的方式是什么
- 是 2s 补码存储负数的一种方式
- 如何以编程方式阻止 Linux 操作系统用户空间中的 USB 存储设备
- 字符集在字符串和 wstring 中的存储方式
- 存储资源的最有效方式
- 如何使用 calloc/malloc 等函数对动态创建的存储进行正确排序,使其以 FIFO 方式运行
- 存储浮点数的最佳方式
- 标准是否要求自动存储中的对象对任何类型都具有正确的对齐方式(例如malloc)
- 存储结构矢量的最佳方式
- 存储IPv4/IPv6地址的有效方式
- c++应用程序有标准的数据存储方式吗?
- 是否有一种方法可以改变变量在内存中的存储方式(位大小)