字符集如何存储在字符串和字符串中?

时间:2016-02-11 11:28:51

标签: c++ string unicode utf-8 wstring

所以,我一直在尝试对字符串和字符串进行一些研究,因为我需要了解它们如何为我正在创建的程序工作,所以我也研究了ASCII和unicode,以及UTF-8和UTF -16

我相信我对这些如何工作的概念有一个很好的理解,但我仍然遇到的问题是它们实际上是如何存储在'char','string','wchar_t'和'wstring'中的。

所以我的问题如下:

  1. 哪个字符集和编码用于char和wchar_t?这些类型仅限于使用这些字符集/编码吗?
  2. 如果它们不限于这些字符集/编码,那么如何确定特定字符或wchar_t使用哪种字符集/编码?例如,它是在编译时自动决定还是我们必须明确告诉它要使用什么?
  3. 根据我的理解,UTF-8在使用集合中的前128个代码点时使用1个字节,但在使用代码点128及以上时可以使用1个以上的字节。如果是这样,这是如何存储的?例如,如果只使用1个字节,它是否与ASCII完全相同?以及type(char或wchar_t或其他)如何知道它使用了多少字节?
  4. 最后,如果我的理解是正确的,我会明白为什么UTF-8和UTF-16不兼容,例如。在需要wstring的地方不能使用字符串。但是在一个需要wstring的程序中,最好将一个转换函数从一个字符串写入一个wstring,当需要一个wstring使我的代码完全基于字符串或者只需要在需要的地方使用wstring时使用它? / LI>

    谢谢,如果我的任何问题措辞不正确或者使用了错误的术语,请告诉我,因为我正试图尽可能地掌握这些问题。

    我正在使用C ++ btw

4 个答案:

答案 0 :(得分:1)

  1. 他们使用您想要的任何字符集和编码。这些类型并不意味着特定的字符集或编码。他们甚至不暗示角色 - 你可以愉快地与他们做数学问题。不要这样做,这很奇怪。

  2. 如何输出文字?如果是控制台,则控制台决定与每个值关联的字符。如果是某个图形工具包,则工具包决定。控制台和工具包往往符合标准,因此现在很可能会使用unicode。在旧系统上可能发生任何事情。

  3. UTF8与ASCII的值相同,范围为0-127。在它之上它变得有点复杂;这在这里解释得很好:https://en.wikipedia.org/wiki/UTF-8#Description

  4. wstring是一个由wchar_t组成的字符串,但遗憾的是wchar_t在不同平台上的实现方式不同。例如,在Visual Studio上它是16位(并且可以用于存储UTF16),但在GCC上它是32位(因此可以用于直接存储unicode代码点)。如果您希望代码可移植,则需要注意这一点。我个人选择只存储UTF8中的字符串,并仅在需要时进行转换。

答案 1 :(得分:1)

  

char和wchar_t使用哪个字符集和编码?这些类型仅限于使用这些字符集/编码吗?

这不是由语言标准定义的。每个编译器都必须与操作系统就要使用的字符代码达成一致。我们甚至不知道charwchar_t使用了多少位。

在某些系统上char是UTF-8,在其他系统上它是ASCII或其他系统。在IBM大型机上,它可以是EBCDIC,这是在定义ASCII之前已经使用的字符编码。

  

如果它们不限于这些字符集/编码,那么如何确定特定字符或wchar_t使用哪种字符集/编码?它是自动在编译时决定的,或者我们是否必须明确告诉它使用什么?

编译器知道什么适合每个系统。

  

根据我的理解,UTF-8在使用集合中的前128个代码点时使用1个字节,但在使用代码点128及以上时可以使用1个以上的字节。如果是这样,这是如何存储的?例如,如果只使用1个字节,它是否与ASCII完全相同?以及type(char或wchar_t或其他)如何知道它使用了多少字节?

UTF-8的第一部分与相应的ASCII代码相同,并存储为单个字节。较高的代码将使用两个或更多字节。

char类型本身只存储字节,不知道形成字符需要多少字节。那是别人决定的。

同样适用于wchar_t,在Windows上为16位,在其他系统上为32位,如Linux。

  

最后,如果我的理解是正确的,我会明白为什么UTF-8和UTF-16不兼容,例如。在需要wstring的地方不能使用字符串。但是在一个需要wstring的程序中,最好将一个转换函数从一个字符串写入一个wstring,当需要一个wstring使我的代码完全基于字符串或者只需要在需要的地方使用wstring时使用它? / p>

您可能需要转换。不幸的是,对于不同的系统,所需的转换会有所不同,因为字符大小和编码会有所不同。

在以后的C ++标准中,您有新类型char16_tchar32_t,其字符串类型为u16stringu32string。那些已知大小和编码。

答案 2 :(得分:0)

关于使用的编码的一切都是实现定义的。检查编译器文档。它取决于默认locale,源文件和操作系统控制台设置的编码。

类似stringwstring的类型,对它们的操作以及C设施,如strcmp / wstrcmp期望固定宽度编码。因此,对于像UTF8或UTF16这样的可变宽度的(但是可以使用例如UCS-2),它将无法正常工作。如果要存储可变宽度编码的字符串,则需要小心,不要对其使用固定宽度操作。 C-string确实有some functions来处理标准库中的这些字符串。你可以使用codecvt标题中的类来转换C ++字符串的不同编码。

我会避免wstring并使用C ++ 11精确宽度字符串:std::u16stringstd::u32string

答案 3 :(得分:0)

以下是一些关于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系统功能。