c++ - 不同的字符集有什么用?

标签 c++ encoding utf-8

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

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

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

    最佳答案

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

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

    a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 _ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " ’

    and the 5 special characters space (' '), horizontal tab (\t), vertical tab (\v), form feed (\f), and newline (\n)



    物理源字符集和基本字符集之间的映射是实现定义的。
  • 基本执行字符集和基本执行宽字符集是能够表示由一些特殊字符扩展的基本源字符集的字符集:

    alert ('\a'), backspace ('\b'), carriage return ('\r'), and a null character ('\0')



    非宽版和宽版的区别在于字符是否用char表示或 wchar_t .
  • 执行字符集和执行宽字符集是基本字符集和基本宽字符集的实现定义的扩展。在 2.3 [lex.charset] 的第 3 段中指出,执行字符集的附加成员和附加成员的值是特定于语言环境的。不清楚引用的是哪个语言环境,但我怀疑编译期间使用的语言环境是指。在任何情况下,执行字符集都是实现定义的(也根据 2.3 [lex.charset] 第 3 段)。
  • 字符和字符串文字最初使用基本源字符集表示,其中一些字符可能使用通用字符名称。所有这些都在编译时转换为执行字符集。根据 2.14.3 [lex.ccon] 字 rune 字可表示为一个 char在执行字符集中只是工作。如果多个 char s 需要字 rune 字可能有条件地支持(并且它们的类型为 int )。对于字符串文字,转换在 2.14.5 [lex.string] 中描述。第 9 段指出 UTF-8 字符串文字(例如 u8"hello")产生与 UTF-8 字符串的代码单元对应的值序列。否则,字符和通用字符名称的翻译与字 rune 字的翻译相同(特别是它是实现定义的),尽管导致窄字符串的多字节序列的字符只会导致多个字符(这种情况不需要支持)对于字 rune 字)。

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

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

    相应地,当使用执行字符集之一编写字符时,这些字符将根据当前语言环境指定的编码进行转换。同样,如果需要特定的编码,则可能需要替换语言环境。

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

    关于c++ - 不同的字符集有什么用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27872517/

    相关文章:

    c++ - 插入 C++ 映射 STL 容器失败

    ruby - 试图理解 Ruby .chr 和 .ord 方法

    python - 如何在 python 2.5 中将 UTF8 字符串转换为 HTML 字符串以正确显示重音?

    c++ - 函数返回另一个函数的返回值

    c++ - 在 C++ 中计算巨大的斐波那契数模 M

    C 结构的 C++ 类包装器

    node.js - Nodejs - 使用 Dropbox Core API 下载 PDF 并保存到磁盘

    java - 通过邮件发送非英文文本的问题

    php - MySQL 到 php 字符集问题

    encoding - 如何使用UTF-8编码的SQLite ODBC驱动程序?