用于什么不同的字符集?

Die*_*ühl 7 c++ encoding utf-8

C++标准提到了多个不同的字符集.特别是,它提到了以下字符集:

  1. 在2.2 [lex.phases] bullet中,提到了1个物理源文件字符及其到基本源字符集的映射.
  2. 在2.2 [lex.phases] bullet 中,提到了2个执行字符集.
  3. 在2.3 [lex.charset]第3段中,提到了基本执行字符集基本执行宽字符集.
  4. 2.3 [lex.charset] 3的相同部分也提到了执行字符集执行宽字符集.
  5. 在读取或写入文件时,请使用其他一些字符集.

那些不同的字符集用于什么,它们之间的转换是如何完成的,以及这些值中哪些是依赖于语言环境的?特别是,字符串文字如何表示?

Die*_*ühl 10

下面是编译器本身使用的不同字符集的细分(实际上所有对标准的引用都是针对C++ 14的):

  1. 所述物理源文件中的字符是那些在C++源使用.现在很可能使用某些Unicode编码对它们进行编码,例如UTF-8UTF-16.如果您来自欧洲或美国背景,您可能正在使用ASCII,其字符在UTF-8中以相同方式编码(每个ASCII文件都是UTF-8文件,但不是相反).物理源文件characters_也可能像EBCDIC一样不寻常.
  2. 基本源代码字符集是什么编译器,至少在概念上,消耗.它由物理源文件字符生成,并将它们映射到各自的基本字符或使用通用字符名称表示物理源字符的基本字符序列(请参阅2.2 [lex.phases]第1段).基本源字符集只是一组96个字符(2.3 [lex.charset]第1段):

    abcdefghijklmnopqrstu vwxyz ABCDEFGHIJKLMNOPQRSTU VWXYZ 0 1 2 3 4 5 6 7 8 9 _ {} []#()<>%:; .?*+ - /^&| 〜!=,\"'

    和5个特殊字符空格(''),水平制表符(\ t),垂直制表符(\ v),换页符(\ f)和换行符(\n)

    物理源字符集和基本字符集之间的映射是实现定义的.

  3. 基本执行字符集基本执行宽字符集是字符设置能够表示由几个特殊字符扩大的基本来源字符集的:

    alert('\ a'),退格('\ b'),回车符('\ r')和空字符('\ 0')

    非宽版和宽版之间的区别在于是否使用char或表示字符wchar_t.

  4. 执行字符集执行宽字符集是基本字符集和基本宽字符集的实现中定义的扩展.在2.3 [lex.charset]第3段中,声明附加成员和执行字符集的附加成员的值是特定于语言环境的.目前尚不清楚引用哪个语言环境,但我怀疑在编译期间使用的语言环境是有意义的.在任何情况下,执行字符集都是实现定义的(也是根据2.3 [lex.charset]第3段).

  5. 字符和字符串文字最初使用基本源字符集表示,其中一些字符可能使用通用字符名称.所有这些都在编译时转换为执行字符集.根据2.14.3 [lex.ccon]字符文字可表示为char执行字符集中的一个只是工作.如果char需要多个s,则可以有条件地支持字符文字(并且它们具有类型int).对于字符串文字,转换在2.14.5 [lex.string]中描述.第9段规定UTF-8字符串文字(例如u8"hello")导致一系列值对应于UTF-8字符串的代码单元.否则,字符和通用字符名称的翻译与字符文字的翻译相同(特别是,它是实现定义的)尽管导致窄字符串的多字节序列的字符只会导致多个字符(这种情况不是必需的支持)对于字符文字).

到目前为止,只考虑了编译的结果.任何不属于字符或字符串文字的字符都用于指定代码的作用.有趣的问题是文字发生了什么?文字基本上都被翻译成实现定义的表示.这是实现定义意味着它在某处记录了应该发生的事情,但它可以在不同的实现之间有所不同.

在处理来自某个地方的字符或字符串时,这有什么用?好吧,任何读取的字符或字符串都将转换为相应的执行字符集.特别是,当读取文件时,所有字符都转换为此公共表示.当然,要使此转换起作用,需要根据该文件的编码来设置用于读取文件的语言环境.如果未明确提及区域设置,则使用最初由系统确定使用的全局区域设置.初始全局区域设置可能基于用户偏好以某种方式设置,例如,基于没有环境变量.如果读取的文件使用的编码与此全局区域设置不同,则需要使用与文件编码匹配的相应不同区域设置.

相应地,当使用一个执行字符集写入字符时,根据当前语言环境指定的编码对它们进行转换.同样,如果需要特定编码,可能需要替换语言环境.

所有这些实际上意味着在程序内部使用实现定义的执行字符集进行所有字符串和字符处理.程序读取的所有字符都需要转换为该字符集,并且所有写入的字符在此执行字符集中以字符开头,需要适当地转换为外部编码.如果当然,在理想的设置中,执行字符集和外部表示之间的转换是标识,例如,因为执行字符集使用UTF-8并且外部表示也使用UTF-8.相应地,对于执行宽字符集,除了在这种情况下将使用UTF-16(两种变体之一,因为UTF-16可以使用大端或小端表示).