内部和外部编码与Unicode

由于在这个问题的评论中有很多海报传播的错误信息: C ++ ABI问题清单

我已经创build了这个澄清。

  1. 什么是用于C风格string的编码?
  2. Linux使用UTF-8编码string?
  3. 外部编码如何与窄string和宽string使用的编码相关?

  1. 实现定义。 甚至应用程序定义; 该标准并没有对应用程序对它们做什么限制,并且期望很多依赖于语言环境的行为。 所有真正实现的定义是在字符串中使用的编码。

  2. 凭什么。 大部分操作系统都忽略了大部分的编码。 如果'\0'不是一个'\0'字节,那么你将会遇到问题,但是即使EBCDIC也符合这个要求。 否则,取决于上下文,将会有一些额外的字符,可能是重要的(例如路径名中的'/' )。 所有这些都使用Unicode中的前128个编码,所以在UTF-8中将有单字节编码。 作为一个例子,我在Linux下使用了UTF-8和ISO 8859-1作为文件名。 唯一真正的问题是显示它们:例如,如果您在xterm执行ls ,则lsxterm将假定文件名与显示字体的编码方式相同。

  3. 这主要取决于语言环境。 根据语言环境,窄字符串的内部编码很可能不与用于字符串的内部编码相对应。 (但是怎么会这样,因为字符串文字的编码必须在编译时确定,因为窄字符串的内部编码取决于用于读取它的区域设置,并且可能因字符串而异。 )

如果您在Linux中开发一个新的应用程序,我强烈建议使用Unicode来处理所有内容,UTF-32用于宽字符字符串,UTF-8用于窄字符串。 但不要指望在字符串文字中工作的前128个编码点之外的任何东西。

  1. 这取决于体系结构。 大多数Unix体系结构对宽字符串( wchar_t )使用UTF-32,对( char )使用ASCII。 请注意,ASCII只是7位编码。 Windows直到Windows 2000使用UCS-2,更高版本使用变量编码UTF-16(对于wchar_t )。
  2. 大多数Linux上的系统调用都是编码不可知的(他们不关心编码是什么,因为他们没有以任何方式解释它)。 外部编码实际上是由您当前的语言环境定义的。
  3. 窄字符串和宽字符串使用的内部编码是固定的,它不会随着语言环境的变化而改变。 通过改变语言环境,您可以编辑和编码进入/离开程序的数据(假设您使用标准的C文本功能)的翻译功能。